【问题标题】:how can I do an implicit conversion from a lambda expression to a custom class?如何进行从 lambda 表达式到自定义类的隐式转换?
【发布时间】:2014-02-24 10:26:59
【问题描述】:

我为惰性参数传递创建了一个类:

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&lt;TimeSpan&gt;,然后转换为LazyValue&lt;TimeSpan&gt;

我知道我可以通过添加显式转换来编译该东西,如下所示:

SomeMethod(arg1, new Func<TimeSpan>(() => my_expression_here))

...但是那样做会很痛苦。我想避免显式转换的语法开销。我真的更喜欢写:

SomeMethod(arg1, () => my_expression_here)

我还可以将 param2 的类型更改为 Func&lt;TimeSpan&gt; 并在方法本身中转换为 LazyValue,但这对我来说似乎不太优雅。

有没有办法让 LazyValue&lt;T&gt; 的隐式转换适用于 lambda?我真的很想让这个工作:

TimeSpan oneHour = TimeSpan.FromHours(1);
SomeMethod(arg1, oneHour);
SomeMethod(arg1, () => Settings.Instance.GetTimeSpan("mysetting"));

【问题讨论】:

  • SomeMethod 期待Func&lt;LazyValue&lt;TimeSpan&gt;&gt; 并使用方法组/lambda 来调用它怎么样? SomeMethod(arg1, my_expression_here)SomeMethod(arg1, () =&gt; my_expression_here),或者你可以只提供一个重载。我敢肯定有一些框架只是为此使用重载

标签: c# lambda implicit-conversion


【解决方案1】:

你是对的,编译器不会链接隐式转换,那就是你必须显式实例化 new Func&lt;TimeSpan&gt;(() =&gt; my_expression_here)

来自Implicit and Explicit Conversion Operators in C#

转换也不能自动链接。如果您有将 Dog 类型转换为 Cat 以及将 Cat 类型转换为 Mouse 的转换,则不能将 Dog 直接分配给 Mouse。

【讨论】:

  • 编译器不会链接 user-defined 隐式转换,但会将一个标准隐式转换从 src 和一个标准隐式转换链接到目标,并在.但是,我发现了为什么这不起作用-只有标准的隐式转换与用户定义的转换链接在一起,而将 lambda 表达式(或匿名方法)转换为委托不是其中之一(规范 6.3.1)。
猜你喜欢
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
相关资源
最近更新 更多