簡體   English   中英

為什么&#39;struct Nullable <T> &#39;不是結構?

[英]Why is 'struct Nullable<T>' not a struct?

基本上為什么C#中的以下內容無效? 我可以找到很多好的用途,實際上可以通過創建我自己的可空結構類來修復它,但C#規范(以及編譯器)為什么以及如何阻止它呢?

以下是我所說的部分例子。

struct MyNullable<T> where T : struct
{
    public T Value;
    public bool HasValue;

    // Need to overide equals, as well as provide static implicit/explit cast operators
}

class Program
{
    static void Main(string[] args)
    {
        // Compiles fine and works as expected
        MyNullable<Double> NullableDoubleTest;
        NullableDoubleTest.Value = 63.0;

        // Also compiles fine and works as expected
        MyNullable<MyNullable<Double>> NullableNullableTest;
        NullableNullableTest.Value.Value = 63.0;

        // Fails to compile...despite Nullable being a struct
        // Error: The type 'double?' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'ConsoleApplication1.MyNullable<T>'
        MyNullable<Nullable<Double>> MyNullableSuperStruct;
    }
}

這是一個struct 它只是不滿足值類型泛型類型參數約束。 從10.1.5的語言規范:

值類型約束指定用於type參數的類型參數必須是非可空值類型。 具有值類型約束的所有非可空結構類型,枚舉類型和類型參數都滿足此約束。 請注意,雖然歸類為值類型,但可空類型(第4.1.10節)不滿足值類型約束。

那么, where T : struct並不代表你認為它意味着什么。

基本上為什么C#中的以下內容無效?

因為where T : struct只能由不滿足值的類型的T來滿足。 Nullable<TNonNullableValueType>不滿足此約束。

為什么以及編譯器如何阻止它呢?

為什么? 符合規范。 怎么樣? 通過執行語法和語義分析並確定您提供了一個不滿足泛型類型約束的泛型類型參數Twhere T : struct

[I]可以通過創建我自己的可空結構類來修復它

不,你的版本沒有修復它。 它基本上與Nullable<T>完全相同,除非您沒有得到編譯器的特殊處理,並且您將導致編譯器的實現不會打包的一些裝箱。

我可以找到很多好的用途

真? 如? 請記住, Nullable<T>的基本思想是擁有一個可以包含T的存儲位置,或者可以表示“缺少值”。 嵌套這個有什么意義? 也就是說, Nullable<Nullable<T>>什么? 它甚至沒有概念意義。 這可能就是它被禁止的原因,但我只是在猜測( Eric Lippert已經證實這種推測是正確的 )。 例如,什么是int?? 它表示一個存儲位置,表示缺少值或是一個int? ,它本身是一個存儲位置,表示缺少值或是一個int 什么用途?

結構約束撥號為nullables的一個原因是我們希望能夠使用T? 在通用方法中。 如果struct允許可以為空的值類型,編譯器將不得不禁止T?

在其他情況下,可空類型必須在編譯器中具有特殊處理:

  • null關鍵字必須可以隱式轉換為可空類型; 對於值類型,這是不可能的。
  • 可以將Nullable值類型與null關鍵字進行比較; 對於不可為空的值類型,此比較始終返回false。
  • 可空值類型適用於?? 操作; 非nullables不。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM