3

我正在尝试动态构建类似于 C# 类型初始化器的东西:

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 命名空间非常熟悉,过去我也做过一些类似这样的中等复杂的事情,但这个让我很困惑。我想构建一个编译的委托,而不是简单地使用反射遍历属性。

谢谢!

4

3 回答 3

1

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

在那之前,你正在寻找一个代码生成工作。对其进行原型设计的最快方法是在 StringBuilder 中构建 C#,然后在其上调用编译器。使用缓存它会执行得很好。

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

于 2010-02-19T19:26:57.603 回答
1

Uh, yeah so I was just making things way too complicated for myself. This is the method I was looking for:

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;            
}
于 2010-02-19T19:54:23.323 回答
0

不幸的是,我没有看到这种情况发生,尽管我不是深伏都教的专家,你可以用表达式和代表来做。

The way I see it, you can only do this with reflection. Without reflection, you need to know at compile time what the names of each property you want to set are. You could do individual functions for each separate class you wanted to support, but that seems counter to the requirement of a generic, one-size-fits-all function.

May I ask why the function in the first place? Some form of dependency injection?

于 2010-02-19T19:30:00.263 回答