";对象不包含<;字段>";使用反射

本文关键字:quot 反射 gt 包含 对象 lt 字段 | 更新日期: 2023-09-27 17:57:56

我有一个库和控制台程序,它可以动态加载.dll文件。在图书馆里我有一个List<User>。库中存在类User。我想在我的foreach中列出列表中的每个用户,但我不知道如何做到这一点。

public class Class1
{
    public List<User> user;
    public Class1()
    {
        user = new List<User>() { 
             new User() { name = "Smith", age = 19 }, 
             new User() { name = "Mitchell", age = 41 } 
        };
    }
}
public class User
{
    public String name;
    public int age;
}

控制台程序部分代码:

Assembly asm = Assembly.LoadFile(@"C:'TestLibrary.dll");
Type Class1 = asm.GetType("TestLibrary.Class1") as Type;
Type User = asm.GetType("TestLibrary.User") as Type;
var testClass = Activator.CreateInstance(Class1);
MemberInfo[] List = Class1.GetMember("user");
FieldInfo field = (FieldInfo)List[0];
MemberInfo[] List = Class1.GetMember("user", BindingFlags.Public | BindingFlags.Instance);
FieldInfo field = (FieldInfo)List[0];                
var users = field.GetValue(testClass); 
for (int i = 0; i < ((IList)users).Count; i++)
{
    var us = ((IList)users)[i];
    // How to show name and age?
    // Console.WriteLine("User: {0}, Age: {1}", us.name, us.age); 
}

附言:我编辑了代码。

";对象不包含<;字段>";使用反射

如果可以将user公开,则:

var assembly = Assembly.LoadFile(@"C:'TestLibrary.dll");
var type = assembly.GetType("TestLibrary.Class1");
dynamic test = Activator.CreateInstance(type);
foreach(dynamic user in test.user)
    Console.WriteLine("User: {0}, Age: {1}", user.name, user.age);
  1. 您正在重新使用变量,因此您的代码甚至不会按原样编译
  2. 默认情况下,您的字段是私有的,因此尝试在不指定BindingFlags.NonPublic的情况下访问它将失败。(您第二次添加标志,但不是第一次)将其设为public:

    public List<User> user;
    

    (你也可以通过添加{get; set;}使其成为一个属性,但由于这整件事在我看来是一个反思练习,所以没有太大区别

  3. 您将该值强制转换为IList,因此在对其进行迭代时,您只看到object s,而不是User s。因此,尝试访问us.name将失败。你可以做:

    for (int i = 0; i < ((IList)users).Count; i++)
    {
        var us = ((IList<User>)users)[i];
        // How to show name and age?
        Console.WriteLine("User: {0}, Age: {1}", us.name, us.age); 
    }
    

    或简称

    foreach(User us in (IList<User>)users)
    {
        // How to show name and age?
        Console.WriteLine("User: {0}, Age: {1}", us.name, us.age); 
    }