【发布时间】:2011-07-05 00:47:26
【问题描述】:
我需要类似这样的方法:
// 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> 的使用,似乎都很愚蠢。一定有更好的办法吗?
注意:由于本示例范围之外的原因,我需要使用表达式类型,而不仅仅是委托。
【问题讨论】:
标签: c# delegates lambda expression-trees