我需要一种类似的方法:
// takes in a DefaultValue type as an Expression Function, with an argument
public void Register<T, TDefaultValueArgs>(Expression<Func<TDefaultValueArgs, T>> defaultValue)
{
// stuff happens here.....
}
我想添加两个重载版本的方法。其中defautlValue是T的简单实例,另一个是defaultValue是没有参数的表达式函数。
我想出了这个(未经测试的)解决方案:
// takes in a DefaultValue type
public void Register<T>(T defaultValue)
{
// The statement below would be better, but isn't valid: "A lambda expression with a statement body cannot be converted to an expression tree"
// Expression<Func<object, T>> defaultValueFunc = (o) => { return defaultValue; };
Expression<Func<DefaultValueContainer<T>, T>> defaultValueFunc = (m => m.GetDefaultValue(defaultValue));
Register<T, DefaultValueContainer<T>>(defaultValueFunc);
}
// takes in a DefaultValue type as an Expression Function
public void Register<T>(Expression<Func<T>> defaultValue)
{
// The statement below would be better, but isn't valid: "A lambda expression with a statement body cannot be converted to an expression tree"
// Expression<Func<object, T>> defaultValueFunc = (o) => { return defaultValue.Compile().Invoke(); };
Expression<Func<DefaultValueContainer<T>, T>> defaultValueFunc = (m => m.GetDefaultValue(defaultValue));
Register<T, DefaultValueContainer<T>>(defaultValueFunc);
}
private class DefaultValueContainer<T>
{
public DefaultValueContainer()
{ }
public T GetDefaultValue(T defaultValue)
{
return defaultValue;
}
public T GetDefaultValue(Expression<Func<T>> defaultValue)
{
return defaultValue.Compile().Invoke();
}
}
我接着假设,在我原来的Regsiter<T, TDefaultValueArgs>
方法中,我可以做这样的事情:
T resolvedDefaultValue = default(T);
if (typeof(TDefaultValueArgs).Equals(typeof(DefaultValueContainer<T>)))
{
var defaultValueContainer = Activator.CreateInstance<TDefaultValueArgs>();
resolvedDefaultValue = defaultValue.Compile().Invoke(defaultValueContainer);
}
所有这一切,包括使用DefaultValueContainer<T>
,似乎都很愚蠢。必须有更好的方法吗?
注意:出于本示例范围之外的原因,我需要使用表达式类型,而不仅仅是委托。
答案 0 :(得分:0)
您可以将lambdas更改为表达式lambda,而无需使用包装类。
你想要的代码(但没有用):
Expression<Func<object, T>> defaultValueFunc =
(o) => { return defaultValue; };
你应该拥有什么:
Expression<Func<object, T>> defaultValueFunc =
(o) => defaultValue;
同样,而不是:
Expression<Func<object, T>> defaultValueFunc =
(o) => { return defaultValue.Compile().Invoke(); };
你应该:
Expression<Func<object, T>> defaultValueFunc =
(o) => defaultValue.Compile().Invoke();
进行这些更改应该允许您使用原始Register<T>
方法。
另外,我不确定这是否只是在编写问题时出错,但您可能希望在原始方法中对齐泛型类型参数,以便它们与Func&lt;&gt;的顺序相同;参数。但是,这只是一种风格狡辩。