C#动态类型初始化程序

时间:2010-02-19 19:22:39

标签: c# reflection delegates dynamic-code

我正在尝试动态构建类似C#type initalizer的东西:

MyClass class = new MyClass { MyStringProperty= inputString };

我想构建一个泛型方法,该方法一次反映给定类型并返回一个委托,该委托创建该类的新实例并根据输入参数填充它。方法签名可能如下所示:

Func<string,T> CreateFunc<T>();

调用结果函数将创建一个新的'T'实例,其中(例如)每个具有String类型的公共属性为输入字符串参数的值。

因此假设'MyClass'只有MyStringProperty,下面的代码在功能上与开头的代码相同:

var func = CreateFunc<MyClass>();
func.Invoke(inputString);

我对System.Reflection和System.Linq.Expressions命名空间非常熟悉,过去我做过一些像这样的中等复杂的事情,但这个让我很难过。我想构建一个已编译的委托,而不是简单地使用反射遍历属性。

谢谢!

3 个答案:

答案 0 :(得分:1)

在CLR 4.0中,您将能够使用表达式构建完整的语句。

在那之前,你正在寻找代码生成工作。原型化最快的方法是在StringBuilder中构建C#然后在其上调用编译器。通过缓存,它可以正常运行。

执行此操作的核心方法是生成IL并使用Reflection Emit构建方法,从而避免调用编译器。

答案 1 :(得分:1)

是的,是的,所以我只是为自己做的事情太复杂了。这是我正在寻找的方法:

public static Func<string, T> CreateFunc<T>()
    where T : class
{
    var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);
    var param = Expression.Parameter(typeof(string),"o");
    var constructorInfo = typeof(T).GetConstructor(new Type[] { });
    List<MemberBinding> bindings = new List<MemberBinding>();
    foreach (var property in properties)
        bindings.Add(Expression.Bind(property, param));

    var memberInit = Expression.MemberInit(Expression.New(constructorInfo), bindings);

    var func = Expression.Lambda<Func<string, T>>(memberInit, new ParameterExpression[] {param}).Compile();

    return func;            
}

答案 2 :(得分:0)

不幸的是,我没有看到这种情况发生,虽然我不是专家,因为你可以用表达式和代表来做深刻的vodoo。

我看到它的方式,你只能用反射做到这一点。如果没有反射,您需要在编译时知道 您想要设置的每个属性的名称。您可以为要支持的每个单独的类执行单独的功能,但这似乎与通用的,一刀切的功能的要求相反。

我可以问一下为什么功能在第一位?某种形式的依赖注入?

相关问题