泛型类型的隐式转换对于接口类型失败

Emi*_*len 4 c# type-inference

        private struct Maybe<T>
        {
            private readonly T value;
            private readonly bool hasValue;

            private Maybe(T value)
            {
                this.value = value;
                hasValue = true;
            }

            public static implicit operator Maybe<T>(T value) =>
                value == null ? new Maybe<T>() : new Maybe<T>(value);
        }

        private static Maybe<byte> OK()
        {
            return 5;
        }

        private static Maybe<IEnumerable<byte>> NotOK()
        {
            var e = new[] { 1, 2, 3 }.Select(x => (byte)x);
            Console.WriteLine(e.GetType().Name);
            return e;
        }
Run Code Online (Sandbox Code Playgroud)

小提琴(不要使用):https : //dotnetfiddle.net/NxAw9l

更新小提琴:https : //dotnetfiddle.net/NrARTl

在上面的代码中,某些泛型类型无法进行隐式转换。请参阅Ok()NotOk()函数调用和返回类型。复杂的泛型类型失败了,我不明白为什么。我从一个返回类型为IEnumerable<IEnumerable<T>>. 这IEnumerable<T>仍然失败。我想如果我能理解为什么会失败,我想我也会解决真正的问题。感谢您的帮助和时间。

如果您愿意,这是错误消息:

Error    CS0029    Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<byte>' to 'Maybe<System.Collections.Generic.IEnumerable<byte>>'
Run Code Online (Sandbox Code Playgroud)

更新:从 NotOK() 返回 Byte[] 无法工作,因为在我的真实源代码中,我有一个 LINQ 查询,我必须依赖其延迟延迟执行(即它必须严格返回 IEnumerable)(参见类似答案=> /sf/answers/4471656311/)。

Hei*_*nzi 5

C# 标准当前不允许从或到接口的隐式转换。

这是在 C# 中实现Maybe<T>(或Optional<T>,通常称为 )类型时的一个众所周知的问题。在 C# 语言 github 论坛上有一个正在进行的讨论:


作为一种解决方法,您可以创建Maybe<T>构造函数internal并添加一个静态非通用帮助程序类:

private static class Maybe
{
    public static Maybe<T> From<T>(T value) => 
        value == null ? new Maybe<T>() : new Maybe<T>(value);
}
Run Code Online (Sandbox Code Playgroud)

它允许您使用类型推断和 write Maybe.From(a),它比new Maybe<IEnumerable<byte>>(a).