Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取c中属性的名称#_C#_Reflection - Fatal编程技术网

C# 获取c中属性的名称#

C# 获取c中属性的名称#,c#,reflection,C#,Reflection,鉴于这一类别: public class MyClass { public int MyProperty {get; set;} } 如何在代码中提取MyProperty的名称 例如,我可以像这样获得类的名称 typeof(MyClass).Name 我怎样才能为物业做类似的事情 这个问题的原因是我希望这个特定的代码能够抵抗名称的重构 编辑:我的意思是,我希望调用站点的代码在面对propertyname的更改时具有健壮性。我有一些东西使用属性名的字符串表示。对不起,措词不当。 我没有

鉴于这一类别:

public class MyClass
{
    public int MyProperty {get; set;}
}
如何在代码中提取
MyProperty
的名称

例如,我可以像这样获得类的名称

typeof(MyClass).Name
我怎样才能为物业做类似的事情

这个问题的原因是我希望这个特定的代码能够抵抗名称的重构

编辑:我的意思是,我希望调用站点的代码在面对propertyname的更改时具有健壮性。我有一些东西使用属性名的字符串表示。对不起,措词不当。
我没有包括调用站点代码,以便保持问题的清晰性,并且不会陷入关于调用站点代码性质的其他讨论。

您可以这样做,使用编译器生成的表达式树:

public static string GetMemberName<T, TValue>(Expression<Func<T, TValue>> memberAccess)
{
    return ((MemberExpression)memberAccess.Body).Member.Name;
}

您现在还可以使用重构重命名该字段,而无需中断此代码

您可以使用以下类,该类包含一个使用表达式树作为参数的方法,以基于lambda表达式确定成员名称:

public class MemberHelper<T>
{
    public string GetName<U>(Expression<Func<T, U>> expression)
    {
        MemberExpression memberExpression = expression.Body as MemberExpression;
        if (memberExpression != null)
            return memberExpression.Member.Name;

        throw new InvalidOperationException("Member expression expected");
    }
}
公共类MemberHelper
{
公共字符串GetName(表达式)
{
MemberExpression MemberExpression=expression.Body作为MemberExpression;
if(memberExpression!=null)
返回memberExpression.Member.Name;
抛出新的InvalidOperationException(“需要成员表达式”);
}
}
然后像这样使用它:

MemberHelper<MyClass> memberHelper = new MemberHelper<MyClass>();
string name = memberHelper.GetName(x => x.MyField);
MemberHelper MemberHelper=newmemberhelper();
字符串名称=memberHelper.GetName(x=>x.MyField);

如果只想获取实例成员的名称,可以使用较短的代码:

    public static string GetMemberName<TValue>(Expression<Func<TValue>> memberAccess)
    {
        return ((MemberExpression)memberAccess.Body).Member.Name;
    }

通过使用反射,您可以通过此项查找
MyClass
中的所有成员

    MemberInfo[] members = typeof(MyClass).GetMembers();
现在,您可以为每个成员找到所需的属性

    foreach ( MemberInfo memberInfo in members)
    {
        Console.WriteLine("Name: {0}", memberInfo.Name); // Name: MyField
        Console.WriteLine("Member Type: {0}", memberInfo.MemberType); // Member Type: Property
    }
如果只想查找属性,请使用
PropertyInfo
而不是
MemberInfo
。 还是写这个

    foreach ( MemberInfo memberInfo in members.Where(p => p.MemberType == MemberTypes.Property))
    {
        Console.WriteLine("Name: {0}", memberInfo.Name); // Name: MyField
        Console.WriteLine("Member Type: {0}", memberInfo.MemberType); // Member Type: Property
    }
使用C#6.0,您可以使用新的
nameof
运算符

nameof(MyClass.MyField)  // returns "MyField"
nameof(MyClass)  //returns "MyClass"
有关更多示例,请参见。

在C#6中,我们可以非常简单地执行此操作

nameof(MyField);
您可以用相同的方法获取方法\type\propery\field\class\namespace名称 前


如果您不想浪费时间,请尝试以下方法。我知道会有人遇到同样的问题

// Soner - tested!
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(item))
{
    string name = descriptor.Name;              // Name
    object value = descriptor.GetValue(item);   // Value
    var type = descriptor.PropertyType;         // Type
    Console.WriteLine($"{name}={value}={type}");
}


不要忘记使用System.ComponentModel添加

这是用于
INotifyPropertyChanged
支持吗?只需使用反射,请参见SO中的示例,例如:添加编辑以回答您的问题和建议。您描述的不是字段。它是一个property@BoppityBop抱歉,今天过得不好,更正了问题以反映我们讨论的是属性而不是字段。使用实例实际上是一个好主意,您不必到处重复类型名称,但类型约束是不必要的。e、 g.为什么这对structs不起作用?@CarstenKönig:你应该这么做?我认为这没有道理。如果用户认为这些东西没有增加价值,他们应该可以随意删除它们。然而,MemberHelper的想法有助于在调用站点获得更流畅的语法。作为一个答案,它并不是毫无用处的。@John Leidegren-你说得对,我最初编写这个类是为了与类一起使用,没有考虑它与结构的潜在用途。已经修改了答案以反映您的建议。@sehe-好的,您有一个要点-think is(我经常遇到这种情况)-如果您运气不好,几秒钟后又发布了基本相同的想法,那么您将很快获得否决票。。。这就是为什么我用同样的内容取消了99%的答案——在这种情况下,一切似乎都很好,所以我删除了我的评论;)这和我标记的另一个答案一样好——它也解决了我的问题。他扣动扳机快了一分钟;)请考虑编辑您的帖子,以添加更多的解释您的代码做什么,为什么它会解决这个问题。一个大多只包含代码的答案(即使它在工作)通常不会帮助OP理解他们的问题。它按预期工作只是不要忘记添加使用System.Linq;在Java中这样做的机会有多大?或者它是C#独特的东西(正如我到目前为止所看到的)?@VitaliPom我对Java知之甚少。这是由C#编译器生成的。非常独特的东西,可能不是Java能做的,其他JVM语言也能做的。如果不是,我会很惊讶。这有多慢?不知何故,它值得缓存吗?@rolls速度慢且昂贵,但首先测量!使用C的
nameof
功能#如果可能的话,它可以用来引用实例成员,比如
nameof(MyClass.Field)
=>“Field”
更好的解决方案。如果您使用的是持续集成(如Jenkins等),请确保至少使用MSBuild版本14.0,以便在那里进行编译,否则它将仅在您的开发机器中进行编译。使用C#6.0的好处要好得多。这是在编译时完成的。正如@John Leidegren所示,可能有理由希望在运行时动态地执行此操作。例如,如果使用模糊处理程序等,编译时名称会发生变化。为什么要对偷来的答案进行更新投票?看,TimestackOverflow按声誉或timestap显示答案??
nameof(MyField);
 nameof(MyClass);
 nameof(namespacename1)  // returns "namespacename1"
 nameof(TestEnum.FirstValue) // returns enum's first value
// Soner - tested!
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(item))
{
    string name = descriptor.Name;              // Name
    object value = descriptor.GetValue(item);   // Value
    var type = descriptor.PropertyType;         // Type
    Console.WriteLine($"{name}={value}={type}");
}