C#反射用法,完全实例化任意类

时间:2014-08-10 01:37:43

标签: c# reflection

我的问题的简短版本是如何在下面的类中实例化和设置每个字段 IF 我在编译时不知道其成员可靠地假设类结构的最小字段是ValueTypeSystem.String字段。

更具体:我已经创建了一个用户控件,就像VS中的监视窗口一样。因此,它是探索对象和设置对象的界面。我已经完成了大会,找到了班级并查看了所有属性并将它们拉出来。这一切都已经完成,我还剩下像

这样的东西
[datum][array] = 4; // intending to make 4 indexes
[datum][0][id] = 100;  
[datum][0][name] = "this data";  
[datum][0][value] = 200; 

现在我想要做的就是弄清楚如何实例化和设置这个数据类。下面是我必须使用的示例类,它们是从XML创建的,因此它们的结构是可预测的。

public partial class myData {

    private myDataDatum datumField;
    public myDataDatum datum {
        get {
            return this.datumField;
        }
        set {
            this.datumField = value;
        }
    }
}
public partial class myDataDatum {
    private string nameField;
    private uint valueField;
    private ushort idField;
    public string name {
        get {
            return this.nameField;
        }
        set {
            this.nameField = value;
        }
    }
    public uint value {
        get {
            return this.valueField;
        }
        set {
            this.valueField = value;
        }
    }
    public ushort id {
        get {
            return this.idField;
        }
        set {
            this.idField = value;
        }
    }
}

我现在正在做什么,这不是一个完整的解决方案,因为我很难尝试使用反射。我不确定如何在数组或其他复杂类型中设置值。

Type type = ClassType;
object _class = Activator.CreateInstance(type);
foreach (PropertyInfo p in type.GetProperties())
{
    for(int i = 0; i<arraySizeof( p.Name ); i++ )
        _class.GetType().GetProperty( p.Name ).SetValue(_class, findValue(p.Name) )
}

findValue(string)方法只计算出所有内容并返回正确的数据。我能弄清楚的是如何解决另一种类型的问题?在将新类型添加到基准数组之前,我是否必须创建该新类型的新实例并分配它的值?


编辑:

当我递归地执行此操作时,这不是必需的,请查看源代码的结构。我就是这样做的,我得到了很多额外的结果,对我来说,这是垃圾数据。

public void walkObject(Type t, string s)
{
  object _class = Activator.CreateInstance(t);
  foreach (var p in _class.GetType().GetRuntimeProperties())
  {

  Debug.WriteLine( "[" + t.Name + "]["+ s +"."+ p.Name + "]\t\t is of type " + p.PropertyType);

  if(p.PropertyType.IsClass && p.PropertyType.Assembly == t.Assembly  )
    walkObject( p.PropertyType, p.Name );
  }
}

现在剩下要做的就是返回对象?或者我如何调用处理.SetValue的调用?

1 个答案:

答案 0 :(得分:0)

当类最基本的参数是简单类型(值或字符串类型)时,有人需要填写任意复杂度的泛型类。

更多:此检查p.PropertyType.IsClass && p.PropertyType.Assembly == t.Assembly是为了确保&#34;复杂&#34; type被识别为动态导入的程序集中的任何类型。

    public object walkObjectConstructor(Type t, ref dynamic x)
    {

        foreach (var p in t.GetRuntimeProperties())
        {
            /* upper level objects */
            if (p.PropertyType.IsClass && p.PropertyType.Assembly == t.Assembly)
            {
                Debug.WriteLine( p.Name );
                object _class = Activator.CreateInstance( p.PropertyType );
                walkObjectConstructor(p.PropertyType, ref _class);
                x.GetType().GetProperty(p.Name).SetValue(x, _class, null);
            }
            /* inside the last upper level object */
            else
            {
                Debug.WriteLine( "\t" + p.Name);
                x.GetType().GetProperty(p.Name).SetValue(x, defaultVal(p.PropertyType), null);
                return null;
            }

        }
        return x;
    }

只需调用defaultVal(parameters to match),将根据需要满足的任何参数查找值的方法将返回正确的值。