如何在运行时设置字段

时间:2015-07-09 20:42:59

标签: c# dynamic types runtime member

我试图设置运行时选择类型的属性,但它总是以MissingFiledException结束。我试图通过InvokeMember方法和Activator.CreateInstance(type)创建Instance。 通常我想从类型中分配字段以键入最简单的方式,它们不是通过接口或派生类相互相似的(例如Data2和AssignmentData类)。

class Program
{
    static void Main(string[] args)
    {
        Data ww =  GetBase(typeof(Data), new AssignmentData(){Id= 5, Text= "qq"}) as Data;
        Data2 ww2 = GetBase(typeof(Data2), new AssignmentData() { Id = 77, Text = "qrrq" }) as Data2;
        Console.ReadLine();
    }

    public static Object GetBase(Type type, AssignmentData ass)
    { 
        List<string> membersName = new List<string>(type.GetMembers().ToList().Select(x => x.Name));
        var obj = Activator.CreateInstance(type);
        //    type.InvokeMember(null, 
        //BindingFlags.DeclaredOnly | 
        //BindingFlags.Public | BindingFlags.NonPublic | 
        //BindingFlags.Instance | BindingFlags.CreateInstance, null, null, null);
        //if(membersName.Any(x => x == "Id"))
        //{
        //    type.InvokeMember("Id", 
        //        BindingFlags.Public | 
        //         BindingFlags.SetField, null, obj, new Object[] {ass.Id});
        //}
        if(membersName.Any(x => x == "Text"))
        {
            type.InvokeMember("Text", 
                BindingFlags.DeclaredOnly | 
                BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.SetField, null, obj, new Object[] { ass.Text });
        }
        return obj;
    }
    public T GetInstance<T>(Type type) where T : Type
    {
        return (T)Activator.CreateInstance(type);
    }
}

class BaseData
{
    public int Id { get; set; }
}

class Data : BaseData
{
    public string Text { get; set; }
}

class Data2 : BaseData
{
    public string Text { get; set; }
}

class AssignmentData
{
    public int Id { get; set; }
    public string Text { get; set; }
}

1 个答案:

答案 0 :(得分:1)

你在最终结果中寻找什么? AssignmentData.Text的值最终是Data.Text或Data2.Text的值?

如果这是你想要的,那么直接设置属性而不是使用InvokeMember。

    ....
    ....
    if(membersName.Any(x => x == "Text"))
    {
        PropertyInfo propInfo = type.GetProperty("Text");
        propInfo.SetValue(obj, ass.Text, null);
    }
    ....
    ....

另外,请注意您尝试将属性设置为字段。您的课程没有名为Text的字段,他们有一个名为Text的属性。如果你真的想使用InvokeMember,那么将BindingFlags.SetField更改为BindingFlags.SetProperty或将Text更改为字段(只是一个公共变量)。

相关问题