我有这样一门课:

internal class MyClass
{
    string name { get; set; }
    List<MyClass2> myClass2 { get; set; }
}

其中MyClass2:

internal MyClass2
{
    string field1 { get; set; }
    string field2 { get; set; }
    int field3 { get; set; }
    long field4 { get; set; }
}

我想通过反射检索myClass2的字段,所以我编写了以下代码片段:

Type objectType = typeof(MyClass);
IEnumerable<MemberInfo> members = objectType
    .GetMembers(BindingFlags.NonPublic | BindingFlags.Instance)
    .Where(p => p.MemberType == MemberTypes.Property);

foreach (var field in members)
{
    if (field.Name != "name")
    {
        var fieldT = field.GetType();
        Console.WriteLine("Field: " + field.Name + "; Field type: " + typeof(Property));
        Type propertiesType = field.GetType();
        IEnumerable<MemberInfo> propertiesMembers = typeof(Property)
            .GetMembers(BindingFlags.NonPublic | BindingFlags.Instance)
            .Where(p => p.MemberType == MemberTypes.Property);
                        
            foreach(var property in propertiesMembers)
            {
                Console.WriteLine("Looking for field: " + field.Name);
                var value = fields.Where(f => f.Key == field.Name).First();
                Console.WriteLine("Actual value receiver for: " + field.Name + " => " + value);
            }
      }
}

其中fields只是一个Dictionary<string, dynamic>,其中包含了问题的非有趣数据.

问题是我无法检索变量myClass2中的字段,首先是因为它是一个集合,其次是因为在循环的fields变量中,它将其类型确定为System.Reflection.RuntimePropertyInfo.

如何修改我的代码以获得myClass2内的字段集合,从而产生我正在寻找的真实数据?这只是MemberTypes.PropertyMemberTypes的会员信息吗?

谢谢.

推荐答案

var fieldT = field.GetType();线并不是你想的那样.fieldMemberInfo实例,因此field.GetType()将与typeof(MemberInfo)相同.

您需要的是属性已声明为的类型,为此,您需要首先强制转换为PropertyInfo:

Type propertiesType = ((PropertyInfo)field).PropertyType;

从那里,您可以检测到属性何时为List<T>,并在该T上进行反思,以获得其上的属性列表:

foreach (var property in members)
{
    if (property.Name != "name")
    {
        //May be null for some built-in types.
        if (property.DeclaringType == null)
            continue;

        var propInfo = (PropertyInfo)property;

        //If this field refers to a List<T>, get the fields of that lists generic type
        if (propInfo.PropertyType.IsGenericType
            && typeof(IList<>).MakeGenericType(propInfo.PropertyType.GenericTypeArguments).IsAssignableFrom(propInfo.PropertyType))
        {
            var fieldType = propInfo.PropertyType.GenericTypeArguments[0];
            var genericListTypeFields = fieldType.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (var innerField in genericListTypeFields)
                Console.WriteLine($"Found property {innerField.Name}");
        }
    }
}

以下哪项输出:

Found property field1
Found property field2
Found property field3
Found property field4

Csharp相关问答推荐

如何在Visual Studio代码中更改大括号模式{},用于C#语言

在FilePath中搜索一个词,并根据First Match从左到右提取文件路径

有没有办法使.NET 6应用程序在特定的.NET 6运行时版本上运行

Rider将.NET安装在哪里

使用可信第三方的Iext8.Net pdf签名

异步任务导致内存泄漏

用于管理System.Text.Json中的多态反序列化的自定义TypeInfoResolver

如何将DotNet Watch与发布配置和传递给应用程序的参数一起使用?

.NET并发词典交换值

在两个已具有一对多关系的表之间添加另一个一对多关系

同一组件的多个实例触发相同的事件处理程序

MudBlazor Textfield已禁用,但其验证工作正常

如何在绑定到数据库的datagridview中向上或向下移动行

获取应用程序版本信息时出现奇怪信息

如果所有";async任务方法()";调用都返回Task.FromResult()-是否同步执行?

反编译源代码时出现奇怪的字符

C# -根据列表所包含的值的数量组织列表- C#

接口中的泛型基类和非泛型子类存在问题

在给定条件下,是否可以将某些变量expose 给Unity判断员?

如何在.NET Core 7中更改Antiforgery cookie路径