简体   繁体   中英

List content of an object dynamicly

There are two kinds of objects:

public class Toto
{
    String test1 = "";
    int test2 = 0;
}

public class Titi
{
    String testA = "";
    int testB = 0;
}

I would create a method which permit me to check dynamicly the content of any object. For example:

public void checkDatas(Object o)

In this method, I would access to test1 and check its value, then test2, then testA, and testB. Like something like this (Object) Object.getMember(new Toto(), "test1")

I found some explanations with the reflection process but nothing works.

Someone have an idea?

Thanks in advance.

You can use reflection to read the members of (unknown) objects, eg:

public class Toto
{
    String test1 = "aaa";
    int test2 = 0;
}

// -------------

Toto t = new Toto();

var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
foreach (FieldInfo field in t.GetType().GetFields(flags))
{
    Console.WriteLine(field.Name + " : " + field.GetValue(t));
}

This produces the following output:

test1 : aaa
test2 : 0

Note: if your classes have private fields, then you must specify the correct BindingFlags when calling Type.GetFields() , as shown above.

You can do something like this, but without knowing more about what 'checking each member' is, I can't really help you more:

public void CheckMembers(object o)
{
    foreach(var member in o.GetType().GetFields())
    {
        object value = member.GetValue(o);
    }
}

I really can't tell why you want something like this, please provide that information if you have it. But can't you do something like this:

var type = o.GetType();
var members = type.GetMembers(BindingFlags.NonPublic|BindingFlags.Public);
foreach(var member in members)
{
    var field = type.GetField(member.Name);
    Console.WriteLine(field.GetValue(o));
}

UPDATE: Use MemberInfo instead of PropertyInfo, and you still should provide us with the information about what you are doing.

Try access instanses in this way instead:

public void checkDatas(Object o)
{
    if (o is Toto)
    {
       (o as Toto).test1 = 0;
    }

    if (o is Titi)
    {
       (o as Titi).testA = "";
    }
}

Note that I assume that the fields are public.

While you could achieve this reflection using string value = typeof(Toto).GetField("test1").GetValue(instance); if you know the types, it's much more efficient just to use to method overloads:

public void CheckObject(Toto toto) { }
public void CheckObject(Titi titi) { }

Or better yet, have both objects conform to an interface, say ICheckable , and that way you only need implement one method:

public void CheckObject(ICheckable checkable);

First of all, Object Oriented programming, an object would not allow you any external sources to view its private fields.

For similar needs, for example to express the content of an object ToString() method can be overridden. Remember the object has to decide on which value to expose.

So in your case you may override ToString like this.

public override string ToString()
{
     return String.Format("Value of test1={0}\nValue of test2={1}", test1, test2);
}

Or try to implement an interface as with method like RevealValues(). Implement this interface in every class that you might want to examine later on.

First of all, I would try to implement some commonality in the objects you want to check.

For example, is it necessary that Toto defines test1 while Titi defines testA? Would it be possible if Toto and Titi defined both test1? That way you would be able to create and common interface for both:

public class Toto
{
    private string test1 = "Hello from Toto object"; 
    public string Test1 { get { return this.test1; } }
}

public class Titi
{
    private string test1 = "Hello from Titi object"; 
    public string Test1 { get { return this.test1; } }
}

Now you can define a common interface:

public interface ICheerfulObject
{
    string Test1 { get; }
}

Make both your classes implement this interface like so:

public class Toto: ICheerfulObject
{
     ....
}

pulbic class Titi: ICheerfulObject
{
     ....
}

And you can then do:

public void CheckData(ICheerfulObject o)
{
    string data = o.Test1;
}

If this scenario is not valid and you really need to use Reflection try the following:

 public void CheckData(object o)
 {
     PropertyInfo property = o.GetType().GetProperty("Test1");  //Get used to using public properties.
     string data = (string)property.GetValue(o, null);
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM