使用反射从对象设置变量不起作用



我想使用反射从对象设置变量。

对于简单对象,这起作用。(属性(

但是具有类变量(字段(的对象不起作用。在这里,我始终获得了"对象不同意目标类型"的exeption。

这里有人想知道它怎么可能发生?

class Program
{
    static void Main(string[] args)
    {
        var genericDataSet = new GenericDataSet<DataObjekt>();
        var returnObjekt = genericDataSet.KeepElementsData();
    }
}
public class DataObjekt
{
    public string Name { get; set; }
    public ObjektData ModelTyp;
    public DataObjekt() { ModelTyp = new ObjektData(); }
}
public class ObjektData
{
    public string Typ { get; set; }
    public string Data { get; set; }
}
public class GenericDataSet<T> where T : class, new()
{
    public T KeepElementsData()
    {
        var item = new T();
        //Propertys durchlaufen
        foreach (var Property in item.GetType().GetProperties())
        {
            item.GetType().GetProperty(Property.Name).SetValue(item, "TestData");  //this works
        }
        //Fields durchlaufen
        foreach (var Field in item.GetType().GetFields())
        {
            foreach (var FieldProperty in item.GetType().GetField(Field.Name).FieldType.GetProperties())
            {
                var data = item.GetType().GetField(Field.Name).FieldType.GetProperty(FieldProperty.Name);
                data.SetValue(item, "TestData not work", null); // this doesent work
            }
        }
        return item;
    }
}

它不起作用的原因是因为您在错误的对象上设置了值:

data.SetValue(item, "TestData not work", null);

item没有此属性,它的字段具有它。
您需要创建一个该字段的实例(如果其为空(,然后填充其属性,然后将其设置为字段。

以下对您有用:

public class GenericDataSet<T> where T : class, new()
{
    public T KeepElementsData()
    {
        var item = new T();
        //Propertys durchlaufen
        foreach (var propertyInfo in item.GetType().GetProperties())
        {
            item.GetType().GetProperty(propertyInfo.Name).SetValue(item, "TestData");  //this works
        }
        //Fields durchlaufen
        foreach (var fieldInfo in item.GetType().GetFields())
        {
            object fieldObject = Activator.CreateInstance(fieldInfo.FieldType);
            // Or if it's already instantiated: 
            // object fieldObject = fieldInfo.GetValue(item);
            foreach (var fieldProperty in fieldInfo.FieldType.GetProperties())
            {
                fieldProperty.SetValue(fieldObject, "TestData not work", null); // this doesent work
            }
            fieldInfo.SetValue(item, fieldObject);
        }
        return item;
    }
}

据我所知,这甚至对属性都不起作用,因为您仅提供字符串数据,而并非所有属性都具有字符串类型。无论如何,在您的田地 - 环境中,为什么您完全有一个嵌套环?您正在循环每个字段 type 的属性,我猜这是相当的。因此,如果您的字段具有类型字符串,则在String的所有字段中迭代所有字段。您应该能够省略内部循环,并为属性编写相同的内容。此外,您可以直接设置当前item的属性值。

var item = new T();
//Propertys durchlaufen
foreach (var property in item.GetType().GetProperties())
{
    property.SetValue(item, "TestData");  //this works
}
//Fields durchlaufen
foreach (var field in item.GetType().GetFields())
{
    field.SetValue(item, "TestData");
}

尝试以下:

public T KeepElementsData()
{
    var item = new T();
    //Propertys durchlaufen
    foreach (var property in item.GetType().GetProperties())
    {
        property.SetValue(item, "TestData");  //this works
    }
    //Fields durchlaufen
    foreach (var field in item.GetType().GetFields())
    {
        var value = field.GetValue(item);
        var type = value.GetType();
        foreach (var fieldProperty in type.GetProperties())
        {
            fieldProperty.SetValue(value, "TestData works");
        }
    }
    return item;
}

您正在属性info->属性info-> propertyinfo的名称之间来回走动...另外,您将item对象与其字段混合在一起...

最新更新