如何在重载方法中传递各种表达式函数
本文关键字:表达式 函数 重载 方法 | 更新日期: 2023-09-27 18:01:00
我需要一个类似的方法:
// 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.....
}
我想添加该方法的两个重载版本。一个是defoutlValue是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>
的使用,似乎都很愚蠢。一定有更好的方法吗?
注意:由于本示例范围之外的原因,我需要使用表达式类型,而不仅仅是委托。
您可以将您的lambda更改为表达式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<>的顺序相同参数。不过,这只是一种风格上的狡辩。