[英]C# Dynamic Type Initializer
我正在尝试动态构建类似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命名空间非常熟悉,过去我做过一些像这样的中等复杂的事情,但这个让我很难过。 我想构建一个已编译的委托,而不是简单地使用反射遍历属性。
谢谢!
在CLR 4.0中,您将能够使用表达式构建完整的语句。
在那之前,你正在寻找一个代码生成工作。 原型化最快的方法是在StringBuilder中构建C#然后在其上调用编译器。 通过缓存,它可以正常运行。
这样做的核心方法是生成IL并使用Reflection Emit构建方法,从而避免调用编译器。
呃,是的,所以我只是让事情变得太复杂了。 这是我正在寻找的方法:
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;
}
不幸的是,我没有看到这种情况发生,虽然我不是专家,因为你可以用表达式和代表做深刻的vodoo。
我看到它的方式,你只能通过反射来做到这一点。 如果没有反射,您需要在编译时知道要设置的每个属性的名称。 您可以为要支持的每个单独的类执行单独的功能,但这似乎与通用的,一刀切的功能的要求相反。
我可以问一下为什么功能在第一位? 某种形式的依赖注入?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.