当您知道要分配的字段的名称时,是否可以将数组分配给未知类型的数组?

时间:2009-11-02 20:25:43

标签: c# reflection covariance

我需要为一个字段分配一个数组。我不知道字段类型,但我确实有一个实例的引用和字段的名称。我可以假设数组可以转换为字段类型。可以这样做吗?

BAS

编辑:

希望这段代码能够澄清我想要做的事情,这会导致在assign中出现异常:

class MyClass
{
    static void Main()
    {
        MyClass t = new MyClass();
        A a = new A();
        C[] c = new C[] {new B()};
        t.Assign(a, "field", c);
    }

    void Assign(object obj, string field, object[] value)
    {
        // crashes
        obj.GetType().GetField(field).SetValue(obj, value);
    }
}

class A
{
    public B[] field;
}

class B : C { }

class C { }

4 个答案:

答案 0 :(得分:5)

instance.GetType()
    .GetField("fieldName", BindingFlags.Instance | BindingFlags.NonPublic)
    .SetValue(instance, array);

答案 1 :(得分:1)

有关详细信息,请参阅reflection page on MSDN

答案 2 :(得分:0)

如果调用它的代码不是时间关键的,你只需使用FieldInfos SetValue()

obj.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic).SetValue(obj, newFieldValue);

如果更频繁地调用代码,您可能希望动态编译setter-delegate。这可以通过例如完成。使用轻量级代码生成:

Action<TObject, TField> ConstructGetter(string fieldName)
{
    System.Reflection.FieldInfo field = typeof(TObject).GetField(fieldName);
    DynamicMethod method = new DynamicMethod(typeof(TObject).ToString() + ":" + "Set:" + name,
                                             null, new Type[] { typeof(TObject), typeof(TField) }, typeof(TObject));
    ILGenerator generator = method.GetILGenerator();
    generator.Emit(OpCodes.Ldarg_0);
    generator.Emit(OpCodes.Ldarg_1);
    generator.Emit(OpCodes.Stfld, field);
    generator.Emit(OpCodes.Ret);
    return method.CreateDelegate(typeof(Action<TObject, TField>)) as Action<TObject, TField>;
}

答案 3 :(得分:0)

所以一个善良的灵魂向我展示了解决方案,享受:)

using System;
using System.Reflection;

class MyClass
{
    static void Main()
    {
        MyClass t = new MyClass();
        A a = new A();
        C[] c = new C[] {new B()};
        t.Assign(a, "field", c);
    }

    void Assign(object obj, string field, object[] value)
    {
        FieldInfo pinfo = obj.GetType().GetField(field);
        Array array = Array.CreateInstance(pinfo.FieldType.GetElementType(), value.Length);
        value.CopyTo(array, 0);
        pinfo.SetValue(obj, array);
    }
}

class A
{
    public B[] field;
}

class B : C { }

class C { }