Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.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# - Fatal编程技术网

C# 通过反射递归查找对象属性?

C# 通过反射递归查找对象属性?,c#,C#,假设我有课 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”作为参数并返回PropertyInfo的方法?我不太理解您的问题 如果要获取类属性

假设我有课

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”作为参数并返回PropertyInfo的方法?

我不太理解您的问题

如果要获取类属性的名称,可以执行以下操作:

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();
}
使用System.Linq;
运用系统反思;
列表属性=GetTypesInNamespace(Assembly.GetExecutionGassembly(),“YourClassNameSpace”);
var propertiesNames=properties.Select(p=>p.Name);
私有列表GetTypesInNamespace(程序集、字符串命名空间)
{
返回assembly.GetTypes().Where(t=>String.Equals(t.Namespace,Namespace,StringComparison.Ordinal)).ToList();
}

假设我们不知道
PropA
PropC
的属性名称,但只知道它们的类型,我们还知道目标类C中属性
字符串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

我已将您的属性公开,以使下面的示例生效:

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;
}

PropA和PropC的名称是固定的还是任意的(可以是任何名称)?如果属性名称无效,只需添加一些验证
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;
}