【问题标题】:Using reflection to set a property of a property of an object使用反射设置对象的属性
【发布时间】:2009-09-09 22:30:35
【问题描述】:

我有两节课。

public class Class1 {
   public string value {get;set;}
}

public class Class2 {
   public Class1 myClass1Object {get;set;}
}

我有一个 Class2 类型的对象。我需要在 Class2 上使用反射来设置 value 属性......也就是说,如果我在没有反射的情况下这样做,我会这样做:

Class2 myObject = new Class2();
myObject.myClass1Object.value = "some value";

有没有办法做到以上,同时使用反射访问属性“myClass1Object.value”?

提前致谢。

【问题讨论】:

  • 这完全可以使用标准反射实现,尽管除非你有通用规则,否则这似乎是一些一次性的逻辑,没有反射可能会更好地完成。
  • @Quintin 我确实意识到我的例子有点做作;但是,我的实际情况实际上比我发布的示例要复杂得多,并且确实要通过反射来完成。

标签: asp.net reflection c#-3.0


【解决方案1】:

基本上将其分为两个属性访问。首先获取 myClass1Object 属性,然后设置结果上的value 属性。

显然,您需要采用属性名称的任何格式并将其拆分 - 例如按点。例如,这应该做任意深度的属性:

public void SetProperty(object source, string property, object target)
{
    string[] bits = property.Split('.');
    for (int i=0; i < bits.Length - 1; i++)
    {
         PropertyInfo prop = source.GetType().GetProperty(bits[i]);
         source = prop.GetValue(source, null);
    }
    PropertyInfo propertyToSet = source.GetType()
                                       .GetProperty(bits[bits.Length-1]);
    propertyToSet.SetValue(source, target, null);
}

诚然,您可能需要更多的错误检查:)

【讨论】:

  • 非常好。我已经冒险尝试获取第一个属性的 PropertyInfo,但是当我尝试调用 SetValue 时遇到了墙,因为我实际上没有源(即,您使用 GetValue 提供了丢失的部分) .谢谢!
  • 谢谢!我有一个递归版本。这个实现要好得多:采用!
  • 我尝试对结构的字段(FieldInfo、Get/SetField 等)做一些等效的事情,但没有任何运气。预计会有不同的行为吗?例如,struct A 包含 struct B,其中包含一个 int i。 SetProperty(source, "B.i", 4) 不会将 a.B.i 更改为 4。有什么想法吗?
  • @Ryan:此时您将获取属性B,它将获取它的副本,改变副本,但随后不分配副本到B。从根本上说,您应该避免使用可变结构,因为它们会使这种事情变得痛苦。
  • @JonSkeet 感谢您的回复。这就说得通了。我通过在 for 循环中将东西(字段和源对象)扔到堆栈上,然后在退出的路上弹出和分配来解决这个问题。它可能不漂亮,但它有效。
【解决方案2】:

我一直在寻找有关在何处获取属性值的情况的答案,当给出属性名称时,但属性的嵌套级别未知。

例如。如果输入是“值”而不是提供完全限定的属性名称,如“myClass1Object.value”。

您的回答启发了我下面的递归解决方案:

public static object GetPropertyValue(object source, string property)
{
    PropertyInfo prop = source.GetType().GetProperty(property);
    if(prop == null)
    {
      foreach(PropertyInfo propertyMember in source.GetType().GetProperties())
      { 
         object newSource = propertyMember.GetValue(source, null);
         return GetPropertyValue(newSource, property);
      }
    }
    else
    {
       return prop.GetValue(source,null);
    }
    return null;
}

【讨论】:

    【解决方案3】:
       public static object GetNestedPropertyValue(object source, string property)
        {
            PropertyInfo prop = null;
            string[] props = property.Split('.');
    
            for (int i = 0; i < props.Length; i++)
            {
                prop = source.GetType().GetProperty(props[i]);
                source = prop.GetValue(source, null);
            }
            return source;
        }
    

    【讨论】:

      猜你喜欢
      • 2010-10-11
      • 1970-01-01
      • 2015-10-13
      • 1970-01-01
      • 2010-10-26
      • 1970-01-01
      • 2014-11-02
      • 1970-01-01
      相关资源
      最近更新 更多