我为lazy参数传递创建了一个类:
public struct LazyValue<T>
{
private Func<T> _fetchFunction;
private bool _fetched;
private T _cachedValue;
public LazyValue(Func<T> fetchFunction)
{
_fetchFunction = fetchFunction;
_fetched = false;
_cachedValue = default(T);
}
public LazyValue(T fixedValue)
{
_fetchFunction = null;
_fetched = true;
_cachedValue = fixedValue;
}
public static implicit operator LazyValue<T>(Func<T> fetchFunction)
{
return new LazyValue<T>(fetchFunction);
}
public static implicit operator LazyValue<T>(T fixedValue)
{
return new LazyValue<T>(fixedValue);
}
public T Value
{
get
{
if (_fetched) { return _cachedValue; }
T value = default(T);
if (_fetchFunction != null)
{
value = _fetchFunction();
}
_cachedValue = value;
_fetched = true;
return value;
}
}
// other members omitted here
}
现在我还有一个接受此类型作为参数的方法:
public ReturnType SomeMethod(SomeType param1, LazyValue<TimeSpan> param2)
我可以使用固定值(TimeSpan实例)调用该方法而不会出现任何问题。 但似乎不可能用param2的lambda表达式调用该方法。编译器抱怨:
Cannot convert lambda expression to type 'LazyValue<System.TimeSpan>' because it
is not a delegate type
我认为这是因为编译器无法进行两步隐式转换:首先将lambda转换为Func<TimeSpan>
,然后转换为LazyValue<TimeSpan>
。
我知道我可以通过添加显式转换来编译,例如:
SomeMethod(arg1, new Func<TimeSpan>(() => my_expression_here))
......但这样做会很痛苦。我想避免显式转换的语法开销。我真的更愿意写:
SomeMethod(arg1, () => my_expression_here)
我还可以将param2的类型更改为Func<TimeSpan>
并在方法本身中转换为LazyValue
,但这对我来说似乎不太优雅。
有没有办法让隐式转换为LazyValue<T>
为lambdas工作?我真的很希望能够做到这一点:
TimeSpan oneHour = TimeSpan.FromHours(1);
SomeMethod(arg1, oneHour);
SomeMethod(arg1, () => Settings.Instance.GetTimeSpan("mysetting"));
答案 0 :(得分:0)
你是对的,编译器不链接隐式转换,你必须明确地实例化new Func<TimeSpan>(() => my_expression_here)
来自Implicit and Explicit Conversion Operators in C#:
转换也无法自动链接。如果您有转换为Cat和Cat键入Dog,则无法将Dog直接分配给鼠标。