繁体   English   中英

C# 中的默认结构不调用隐式运算符

[英]Implicit operator isn't called for default of struct in C#

我正在实施 Haskell 的 Maybe 的 C# 变体,遇到一个奇怪的问题,其中nulldefaultimplicit转换返回的值有不同的含义。

public class TestClass
{
    public void Test()
    {
        Maybe<string> valueDefault = default;
        Maybe<string> valueNull = null;
        Maybe<string> valueFoobar = "foobar";
        Console.WriteLine($"Default: (Some {valueDefault.Some}, None {valueDefault.None}");
        Console.WriteLine($"Null: (Some {valueNull.Some}, None {valueNull.None}");
        Console.WriteLine($"Foobar: (Some {valueFoobar.Some}, None {valueFoobar.None}");
    }
}

public struct Maybe<T>
{
    public T Some { get; private set; }
    public bool None { get; private set; }

    public static implicit operator Maybe<T>(T value)
    {
        return new Maybe<T>() {
            Some = value,
            None = value == null
        };
    }
}

output 是:

默认值:(一些,无假)

Null:(一些,不正确)

Foobar:(一些foobar,没有假)

我期望valueDefaultvalueNull相等。 但似乎null已转换,而default值未转换。 我通过将 None 替换为具有反向 boolean 条件的 HasSome 来解决问题,但问题仍然存在。

为什么 null 和 default 被区别对待?

每种类型都有一个默认值,包括Maybe<T> 请参阅此页面以获取列表。

Maybe<string> valueDefault = default; 会将Maybe<string>的默认值分配给valueDefault Maybe<string>的默认值是多少? 根据那个页面,因为Maybe<string>是一个结构,它的默认值是:

通过将所有值类型字段设置为其默认值并将所有引用类型字段设置为 null 生成的值。

所以它是Maybe<string>的一个实例,其中SomenullNonefalse falsebool的默认值。

编译器不会尝试使用string的默认值,因为这需要进一步转换为Maybe<string> 如果它可以直接使用Maybe<string>的默认值,为什么 go 会很麻烦,对吧?

你可以强制它:

Maybe<string> valueDefault = default(string);

另一方面, null被转换为Maybe<string>因为null不是Maybe<string>的有效值(结构不能是 null,),因此编译器推断您必须null as string ,并且确实隐式转换。


您可能已经知道这一点,但您似乎正在重新发明Nullable<T>

default总是用零字节填充结构的 memory。 null不是值类型的有效值,因此编译器发现隐式(Maybe<string>)(string)null转换。

也许您可以替换为;

public struct Maybe<T>
{
    public T Some { get; private set; }
    public bool None => Some == null;
...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM