【问题标题】:How can I get field's value if it's defined as automatic property?如果将字段定义为自动属性,如何获取字段的值?
【发布时间】:2012-12-14 20:41:51
【问题描述】:

如果字段定义为自动属性,如何获取字段值?
我不知道为什么,但我第一次遇到如此简单的任务,使用这种名为 GetValue 的无法解释的方法,它不能按我的意愿工作,并且通常会抛出各种异常,而不是做原来的简单工作..

一些代码例如:

Class A
{
   public int Age { get; set;}
}

现在假设经过反射,我在 FiledInfo[] 的结构中保存了 A 实例的字段。
现在我在上面的数组中找到了相关的fieldInfo,他的名字是:
{Int32 k__BackingField} 听起来很奇怪,无论如何..
如何使用 GetValue() 来获取 int 值?正如我所说,我尝试了很多东西..

编辑:(这是部分简化的代码 - 不要生气)

private static string foo1<T>(T o)
        {
            var type = o.GetType();
            var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
           ....
            foo(fields);
         }
}

private static void foo(FieldInfo[] fields)  
        {

            foreach (FieldInfo field in fields)
            {

                if (field.FieldType.IsValueType)
                {
                    var fieldNameLength = field.Name.IndexOf(">") - (field.Name.IndexOf("<")+1);
                    var fieldName = field.Name.Substring(field.Name.IndexOf("<")+1, fieldNameLength);
                    var fieldValue = field.ReflectedType.GetProperty(fieldName).GetValue(field.ReflectedType, null)
                }
             }
}

【问题讨论】:

  • 如果它是一个自动属性,并且您在通过反射访问其值时抛出异常,那么您的反射代码可能有问题。在尝试绕过它之前先发布或提出问题。
  • 如果你只是对字段的值感兴趣,为什么不检索属性值呢?它始终与自动属性的字段值相同。
  • 好的,我正在尽快添加我的相关反射代码
  • 请显示您尝试过的代码。目前尚不清楚为什么您无法获取字段的值(即,您在获取自动生成的名称时遇到问题,您不知道如何完全获取字段,其他...)
  • 也试图通过该属性

标签: c# reflection automatic-properties


【解决方案1】:
A a = new A() { Age = 33 };
var age = a.GetType().GetProperty("Age").GetValue(a);

【讨论】:

    【解决方案2】:

    而不是var fieldValue = field.ReflectedType.GetProperty(fieldName).GetValue(field.ReflectedType, null),您应该只使用:var fieldValue = field.GetValue(o, null) 请注意,您需要将o 的实例传递给您。确实,您应该执行 L.B 发布的操作并按名称查找您的属性,或者如果您不这样做知道名字,通过myType.GetProperties枚举他们

    以下是修改后的代码以使用属性:

    private static void foo1<T>(T o)
    {
        var type = o.GetType();
        var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
    
        foo(properties, o);
    }
    
    private static void foo(PropertyInfo[] properties, object o)
    {
        foreach (PropertyInfo property in properties)
        {
            if (property.PropertyType.IsValueType)
            {
                var propertyValue = property.GetValue(o, null);
                //do something with the property value?
            }
        }
    }
    

    编辑:您可能希望确保该属性有一个 getter(请参阅:How do you find only properties that have both a getter and setter?),或者它可能是一个自动属性(请参阅:How to find out if a property is an auto-implemented property with reflection?)但我猜这不一定是要求对你来说,可能只是正确使用 GetValue 方法或如何使用反射来检查类型。

    编辑:如果您仍希望使用字段,请使用相同的代码:

    private static void foo1<T>(T o)
    {
        var type = o.GetType();
        var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
    
        foo(fields, o);
    }
    
    private static void foo(FieldInfo[] fields, object o)
    {
        foreach (FieldInfo field in fields)
        {
            if (field.FieldType.IsValueType)
            {
                var fieldValue = field.GetValue(o);
                //do something with the field value?
            }
        }
    }
    

    【讨论】:

    • 好的,一个问题,我使用的 Getfield 方法还没有包含您使用您的版本搜索的属性
    • @JavaSa 从技术上讲,但我认为你最好还是点击属性,除非有一些特殊原因需要支持字段。某些平台(例如 Silverlight)您无法访问支持字段,因为它是私有的。此外,我认为(我可能错了)支持字段的命名/访问方式是一个实现细节,并且在平台/版本之间可能有所不同。如果您只想查找字段,因为您知道您的类型没有声明字段,因此您可以找到自动属性,然后带着字段去城镇。
    • @JavaSa 我使用字段添加了另一个编辑;它们非常相似。
    • 字段和属性都有它们的用途,因此根据开发人员的需要访问它们是有意义的。我不确定您反映获得这些值的最终目标是什么,因此我无法评论您应该使用哪个值。 通常,如果您定义一个自动属性,那么您只能通过定义的属性访问其内容。至于通过ReflectedType 访问它,我从来没有使用过这个成员(我总是提供对象实例)所以我不确定它为什么会导致问题。我建议您只通过对象引用。
    • @JavaSa 是的,刚刚意识到:ReflectedType 实际上指向的是您在var type = o.GetType() 线上获得的Typenot o 本身。这是一个Type,而不是一个对象实例。编辑:从这个意义上说,您不能按照您的想法使用它(对于不同的用法,这是一个不同的概念)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多