2011-04-05 76 views
2

在C#中,我正在定义一个特定类的静态字段。从类中,我希望能够以显示静态字段的名称,几乎是这样的:C#:有没有办法访问当前字段的名称?

public class Unit { 
    public string NameOfField { get { return ...; } } 
} 

public static Unit Hectare = new Unit(); 

如果我现在访问:

Hectare.NameOfField 

我希望它返回:

Hectare 

我知道有一个静态函数System.Reflection.MethodBase.GetCurrentMethod(),但据我可以告诉有没有办法让这个包含当前方法的实例的名称?

还有System.RuntimeFieldHandle结构,但我一直无法识别任何GetCurrentFieldHandle()方法。

我不知道我是否缺少明显的东西?

对此非常感谢。

+2

从Unit类中无法做到这一点。如果多个变量引用同一个实例会怎么样? – Blorgbeard 2011-04-05 09:15:29

+0

难道你不能只是将名称传递给构造函数并将其存储在单元中的字段中? '公共静态单位公顷=新单位(“公顷”);' – Henrik 2011-04-05 09:17:43

+2

您似乎在询问您的类实例分配给的运行时变量的名称。你不能用c# – IanNorton 2011-04-05 09:22:38

回答

0

感谢大家花时间回答并讨论我的问题。

为了让您知道,我已经实施了一个足以满足我需求的解决方案。这个解决方案不是一般的,它有一些缺陷,但是我认为我可以分享它,以防它可以帮助别人。

这在原则上是什么定义字段时所使用的类的样子:

public class Unit : IUnit { 
    public NameOfField { get; set; } 
    ... 
} 

正如你所看到的,类实现IUNIT接口,和我在NameOfField酒店所提供的公开的setter 。

的静态字段通常被定义这样一些含类中:

public static Unit Hectare = new Unit(); 

我的解决办法是通过反射在执行使用该字段之前设置NameOfField属性。我使用Linq来遍历相关字段的执行程序集,并且当我检测到这些字段时(字段类型实现了这些字段

Assembly.GetExecutingAssembly().GetTypes(). 
    SelectMany(type => type.GetFields(BindingFlags.Public | BindingFlags.Static)). 
    Where(fieldInfo => fieldInfo.FieldType.GetInterfaces().Contains(typeof(IUnit))). 
    Any(fieldInfo => 
    { 
    ((IUnit)fieldInfo.GetValue(null)).NameOfField= fieldInfo.Name; 
    return false; 
    }); 

有一些缺点这种方法:

  • 静态构造函数必须通过人工干预来调用IUNIT接口),我使用的任何扩展方法设置NameOfField属性为他们每个人在任何单位字段可以被访问之前
  • NameOfField setter是公开的。在我的情况下,这是没有问题的,但可能是在其他情况下应用。 (我假设二传手可以通过进一步思考而变得私密并且被引用,但是我没有花时间进一步探索这条路径。)
  • ...?

无论哪种方式,也许这种解决方案可以帮助别人比我。

1

你不应该指望你开发中的变量名,因为它们不会在运行时退出。

这是更好地与直接的名称来初始化单位:

public class Unit { 

    public Unit(string name) 
    { 
    NameOfField = name; 
    } 
    public string NameOfField { get; private set;} } 
} 

public static Unit Hectare = new Unit("Hectare"); 
+0

感谢您的答案Manji。我曾考虑过这个问题,但我有很多静态字段,我想避免所需的重构。但我可能不得不重新考虑... – 2011-04-05 09:52:32

+0

这是更好的是的。也许你可以使用正则表达式来做一个大规模的seach /替换vsiual studio:搜索public [] + static [] + Unit [] + {[^] +} [] + = [] + new [] +单元\(\)'并将其替换为'公共静态单元\ 1 =新单元(“\ 1”)' – manji 2011-04-05 10:07:50

+0

您提供正则表达式真是太好了,它通常是我一天中很大一部分试图自己编写正则表达式:-)正如你可以看到下面我已经实现了一个解决我的具体问题,所以幸运的是我不需要重构。无论如何感谢你的努力。 – 2011-04-05 20:21:42

0

只有这样,围绕这将是存储在类信息:

public static Unit Hectare = new Unit("Hectare"); 

当你的代码被编译所有变量名称丢失并被内部参考代替。没有办法再次获得该名称。

+0

谢谢你的回答杰里。正如我在上面的Manji答案中所提到的,我有很多静态字段,我想避免所需的重构。但如果没有其他出路...... – 2011-04-05 09:54:03

+0

这不是**只有**方式 – 2011-04-05 12:50:42

0

您可以使用反射来获取类字段和属性。如下图所示:

假设你有类一个属性:

class Test 
{ 
    public static string MySupperField 
    { 
     get 
     { 
      return "Some symbols here"; 
     } 
    } 
} 

...... 

您可以用这样的方式读取属性名称:

public string[] GetClassStaticNames(Type T) 
{ 
    string[] names; 

    System.Reflection.PropertyInfo[] props = T.GetProperties(); // This will return only properties not fields! For fields obtaining use T.GetFields(); 

    names = new string[props.Count()]; 
    for (int i = 0; i < props.Count(); i++) 
    { 
     names[i] = props[i].Name; 
    } 

    return names; 
} 

希望这会有所帮助。

[编辑]
回到你的问题 - 不,你不能获得当前的变量的名称。
由于类的性质,你所问的不能做什么,它们是内存中的对象,并且对一个对象的引用可以保存在许多变量中,并且当你请求实例字段或属性的值时,它将被实际执行内存中的对象不与变量保持对该对象的引用。所以获取变量的名称持有对当前实例的引用没有认识

+0

我曾想过从包含类获取字段名称。原则上,我应该能够将当前字段与包含类中的字段列表进行匹配。我希望能有更快的方法,但是我所得到的所有答案在这方面都令人沮丧:-)无论如何,非常感谢答案,安东。 – 2011-04-05 10:01:53

+0

我刚更新了我的答案 – 2011-04-05 10:03:24

+0

再次感谢安东。 @Blorgbeard在上面做了类似的评论。我明白这一点,事实是这个对象可以被许多变量所控制,或多或少地使我的请求失去资格。我将不得不重新考虑我的实施。无论如何,好讨论它。谢谢。 – 2011-04-05 10:13:25

相关问题