簡體   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