动态列出对象的内容

时间:2011-06-01 15:47:53

标签: c# .net reflection dynamic .net-4.0

有两种对象:

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

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

我会创建一个方法,允许我动态检查任何对象的内容。例如:

public void checkDatas(Object o)

在这个方法中,我将访问test1并检查其值,然后是test2,然后是testA和testB。像这样(Object)Object.getMember(new Toto(),“test1”)

我在反思过程中找到了一些解释但没有任何效果。

有人有想法吗?

提前致谢。

7 个答案:

答案 0 :(得分:3)

您可以使用反射来读取(未知)对象的成员,例如:

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

这会产生以下输出:

test1 : aaa
test2 : 0

注意:如果您的班级有私人字段,那么您在调用BindingFlags时必须指定正确的Type.GetFields(),如上所示。

答案 1 :(得分:2)

你可以做这样的事情,但如果不知道'检查每个成员'是什么,我真的无法帮助你更多:

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

答案 2 :(得分:1)

我真的不知道为什么你想要这样的东西,请提供这些信息。但你不能做这样的事情:

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

更新:使用MemberInfo代替PropertyInfo,您仍然应该向我们提供有关您正在做的事情的信息。

答案 3 :(得分:1)

请尝试以这种方式访问​​实例:

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

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

请注意,我假设这些字段是公开的。

答案 4 :(得分:1)

虽然如果你知道类型,你可以使用string value = typeof(Toto).GetField("test1").GetValue(instance);来实现这种反射,但是使用方法重载会更有效:

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

或者更好的是,让两个对象都符合一个界面,比如ICheckable,这样你只需要实现一个方法:

public void CheckObject(ICheckable checkable);

答案 5 :(得分:1)

首先,面向对象编程,一个对象不允许任何外部源查看其私有字段。

对于类似需求,例如表达对象的内容ToString()方法可以被覆盖。请记住,对象必须决定要公开哪个值。

因此,在您的情况下,您可以像这样覆盖ToString。

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

或尝试像RevealValues()这样的方法实现接口。在您稍后可能要检查的每个类中实现此接口。

答案 6 :(得分:1)

首先,我会尝试在您要检查的对象中实现一些共性。

例如,Toto是否有必要定义test1而Titi定义testA?如果Toto和Titi定义了test1,那会有可能吗?这样你就可以为两者创建和共同的界面:

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

现在您可以定义一个通用界面:

public interface ICheerfulObject
{
    string Test1 { get; }
}

让你的类实现这个接口,如下所示:

public class Toto: ICheerfulObject
{
     ....
}

pulbic class Titi: ICheerfulObject
{
     ....
}

然后你可以这样做:

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

如果此方案无效且您确实需要使用Reflection,请尝试以下操作:

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