【问题标题】:Recursively find object property via reflection?通过反射递归查找对象属性?
【发布时间】:2016-01-24 03:48:01
【问题描述】:

假设我有课,

class A
{
  B PropA{get; set;}
}

class B
{
  string PropB{get; set;}
  C PropC{get; set;}
}

class C
{
  string PropD{get; set;}
}

现在我想得到“PropA.PropB”?同样,我想得到“PropA.PropC.PropD”等等?我需要创建一个将“PropA.PropB”作为参数并返回 PropetyInfo 的方法?

【问题讨论】:

  • PropA 和 PropC 的名称是固定的还是任意的(可以是任何名称)?

标签: c#


【解决方案1】:

我不太明白你的问题...

如果要获取类属性的名称,可以这样做:

using System.Linq;
using System.Reflection;

List<Type> properties = GetTypesInNamespace(Assembly.GetExecutingAssembly(), "YourClassNameSpace");

 var propertiesNames = properties.Select(p => p.Name);

private List<Type> GetTypesInNamespace(Assembly assembly, string nameSpace)
{
    return assembly.GetTypes().Where(t => String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal)).ToList();
}

【讨论】:

    【解决方案2】:
    static class Program
    {
        static readonly BindingFlags flags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
    
        static void Main() {
            var a = new A { PropA = new B() { PropB = "Value" } };
            var prop = GetPropertyRecursive("PropA.PropB", a);
        }
    
        static object GetPropertyRecursive(string property, object obj) {
            var splitted = property.Split('.');
            var value = obj.GetType().GetProperty(splitted[0], flags).GetValue(obj);
    
            if (value == null) {
                return null;
            }
    
            if (splitted.Length == 1) {
                return value;
            }
    
            return GetPropertyRecursive(string.Join(".", splitted.Skip(1)), value);
        }
    }
    

    【讨论】:

    • 如果属性名称无效,只需添加一些验证
    【解决方案3】:

    假设我们不知道 PropAPropC 的属性名称,但只知道它们的类型,并且我们还知道目标类 C 中属性 string PropD 的名称:

    class A
    {
        public B PropA { get; set; }
    }
    
    class B
    {
        public string PropB { get; set; }
        public C PropC { get; set; }
    }
    
    class C
    {
        public string PropD { get; set; }
    }
    
    class Program
    {
        static object GetPValue(Type propType, object obj)
        {
            return obj.GetType().GetProperties()
                .First(p => p.PropertyType == propType).GetValue(obj);
        }
    
        static object GetPValue(string name, object obj)
        {
            return obj.GetType().GetProperty(name).GetValue(obj);
        }
    
        static void Main(string[] args)
        {
            A a = new A();
            B b = new B();
            C c = new C();
            a.PropA = b;
            b.PropB = "B";
            b.PropC = c;
            c.PropD = "C";
    
            object obj = new object();
    
            obj = GetPValue(typeof(C), GetPValue(typeof(B), a));
    
            Console.WriteLine(GetPValue("PropD", obj));
        }
    }
    

    输出:C

    【讨论】:

      【解决方案4】:

      我已公开您的属性以使下面的示例正常工作:

      static void Main(string[] args)
      {
      
          var propertyInfo = GetPropertyInfo(typeof(A), "PropA.PropC");
          Console.WriteLine(propertyInfo.Name);
          Console.ReadLine();
      }
      
      static PropertyInfo GetPropertyInfo(Type type, string propertyChain)
      {
          if (!propertyChain.Contains("."))
          {
              var lastProperties = type.GetProperties().Where(m => m.Name.Equals(propertyChain));
              return lastProperties.Any() ? lastProperties.First() : null;
          }
      
          var startingName = propertyChain.Split('.')[0];
          var found = type.GetProperties().Where(m => m.Name.Equals(startingName));
          return found.Any() ? GetPropertyInfo(found.First().PropertyType, propertyChain.Replace(startingName + ".", "")) : null;
      }
      

      【讨论】:

        猜你喜欢
        • 2015-11-18
        • 2011-09-29
        • 2012-10-03
        • 2011-02-11
        • 1970-01-01
        • 1970-01-01
        • 2014-02-12
        • 2011-09-05
        • 1970-01-01
        相关资源
        最近更新 更多