簡體   English   中英

為什么我們不能使用密封類作為通用約束?

[英]Why we can’t use sealed classes as generic constraints?

你能猜出在泛型中不允許使用密封類進行類型約束的原因是什么? 我只有一個解釋是給機會使用裸約束。

如果類是密封的,則不能繼承。 如果它不能被繼承,它將是泛型類型參數有效的唯一類型[假設允許為類型參數]。 如果它是唯一的泛型類型參數,那么將它變為通用就沒有意義了! 您可以簡單地針對非泛型類中的類型進行編碼。

這是一些代碼。

public class A
{
    public A() { }
}

public sealed class B : A
{
    public B() { }
}

public class C<T>
        where T : B
{
    public C() { }
}

這將給出編譯器錯誤: 'B'不是有效約束。 用作約束的類型必須是接口,非密封類或類型參數。

除此之外,您還可以將靜態類作為泛型類型約束。 原因很簡單。 靜態類被標記為抽象密封在已編譯的IL中 ,既不能實例化也不能繼承。

這是代碼。

public class D<T>
        where T : X
{
    public D() { }
}

public static class X
{
}

這將給編譯器錯誤: 'X':靜態類不能用作約束。

你在談論這樣的事情:

class NonSealedClass
{
}

class Test<T> where T : NonSealedClass
{
}

因為它完全合法。

老實說,我不太明白這一點。

正如這個.__ curious_geek在他的回答中指出的那樣 ,密封的類不能被繼承,因此使用一個作為約束似乎是荒謬的。

但是不能保證密封的類永遠不會被“啟封” - 也就是說,開發人員可能會重新安排其實現以使其更適合繼承,然后從類定義中刪除sealed修飾符(或者只是將其刪除sealed關鍵字無緣無故)。

我知道很多開發人員實際上都鼓勵這種做法:不要刪除sealed關鍵字本身,而是自由地添加 sealed關鍵字,只有在明確做出決定時才支持繼承(此時,是的,刪除sealed關鍵詞)。

所以我不確定為什么你不能使用密封類的類型作為通用約束。 畢竟,你總是可以使用恰好沒有任何派生類的類的類型,即使它沒有被密封。 這兩種情況對我來說似乎並沒有什么不同。

不過,我可能會遺漏一些東西。 我相信Eric Lippert可以給出一個相當殺手的解釋。

裸約束是一個泛型類型從另一個繼承的例如

where X:Y

一個通用參數派生自另一個通用參數

class Foo<T>
{
    Foo<S> SubsetFoo<S>() where S : T {  }
}

因此班級無法封存。

您也可以以正常方式繼承泛型,因此您不希望它們被密封。

暫無
暫無

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

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