[英]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.