Question

I have a library and console program which dynamically loads a .dll file. In the library I have a List<User>. Class User exists in the library. I want in my foreach each user on List, but I don't know how to do that.

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

Part code of console program:

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

P.S. I edited the code.

Was it helpful?

Solution

If you can make user public, then:

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

OTHER TIPS

  1. You are re-using variables so your code as-is won't even compile.
  2. Your field is private by default, so trying to access it without specifying BindingFlags.NonPublic will fail. (You add the flags the second time but not the first time) Make it public:

    public List<User> user;
    

    (you could also make it a property by adding {get; set;} but since this whole thing seems to me an exercise in reflection it doesn't make much difference.

  3. You are casting the value to an IList, so when iterating through it you just see objects instead of Users. So trying to access us.name will fail. You could do:

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

    or simply

    foreach(User us in (IList<User>)users)
    {
        // How to show name and age?
        Console.WriteLine("User: {0}, Age: {1}", us.name, us.age); 
    }
    
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top