我的问题的简短版本是如何在下面的类中实例化和设置每个字段 IF 我在编译时不知道其成员但 可靠地假设类结构的最小字段是ValueType
或System.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的调用?
答案 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)
,将根据需要满足的任何参数查找值的方法将返回正确的值。