[英]C#: Should a nested class in a generic class be considered generic?
namespace GenericsTest
{
public class AGenericClass<T>
{
public class NestedNonGenericClass
{
}
}
}
在上面的例子中, NestedNonGenericClass
應該被視為泛型類嗎?
反射API說它是一個泛型類,甚至把包含類的模板參數作為嵌套類的模板參數。
Type nestedClass = typeof(AGenericClass<int>.NestedNonGenericClass);
Console.Out.WriteLine("IsGeneric: {0}\tHasGenericArguments: {1}",
nestedClass.IsGenericType, nestedClass.GetGenericArguments().Length > 0);
打印出:
IsGeneric:True HasGenericArguments:True
我不完全同意這種行為。 即使編譯器為NestedNonGenericClass
生成泛型類型,我也想知道它是否是泛型的,因為它是聲明的,或者因為它的容器是通用的。
所以,我的問題是:
首先,你認為可以考慮嵌套類泛型,因為它的容器是通用的嗎? 為什么/為什么不呢?
其次,您是否碰巧知道其他一些API可以幫助我只識別聲明為通用的類?
PS:我在ECMA規范中找不到與此相關的任何內容(或者我可能只是掩蓋它)。
- 編輯 -
為了添加更多的上下文,我正在開發一種代碼生成器。 我正在使用反射API來確定類型是否是通用的。
我遇到了Dictionary<TKey, TValue>.KeyCollection
。
對於KeyCollection
,反射API表示它是通用的,並將我交給容器中聲明的TKey
和TValue
。 因此,生成器最終生成Dictionary<TKey, TValue>.KeyCollection<Tkey, TValue>
我能解決這個問題的唯一方法是將嵌套類的模板參數與容器匹配,並消除所有匹配的模板參數。 但我想知道是否有更好的方法。
簡而言之,是 - 一個類型從包含它的任何類型繼承類型參數:這是List<T>.Enumerator
和許多其他場景等的關鍵 - 它們與外層類共享T
是至關重要的(不只是任何T
)。
ECMA參考文獻是§25.1:
嵌套在泛型類聲明或泛型結構聲明(第25.2節)中的任何類本身都是泛型類聲明,因為應提供包含類型的類型參數以創建構造類型。
是的,您的嵌套類絕對是通用的,因為T綁定到嵌套類的任何實例范圍內的類型(這稱為封閉泛型 )。
using System;
using System.Collections.Generic;
public class AGenericClass<T> {
public class NestedNonGenericClass {
public void DoSomething() {
Console.WriteLine("typeof(T) == " + typeof(T));
}
}
}
public class MyClass {
public static void Main() {
var c = new AGenericClass<int>.NestedNonGenericClass();
var d = new AGenericClass<DateTime>.NestedNonGenericClass();
c.DoSomething();
d.DoSomething();
Console.ReadKey(false);
}
}
同樣的DoSomething()
方法根據泛型類型的關閉方式產生不同的輸出 - 所以是的,內部類肯定表現出通用行為。
如果你不打算在NestedNonGenericClass中使用T,你可以將它放在類之外並使其成為私有..那么它就不會是Generic ....
我選擇理解它的方式是,當你使用泛型類型時,C#會生成該類型的所有內容。 實際上,如果我想象一下如果我使用上面例子中的AGenericClass和AGenericClass會產生什么,那么你最終會得到兩個嵌套類的副本:
public class AGenericClass<int>
{
public class NestedNonGenericClass
{
}
}
public class AGenericClass<float>
{
public class NestedNonGenericClass
{
}
}
因此,我認為嵌套類是泛型類,因為它有兩個版本,一個叫做AGenericClass <int> .NestedNonGenericClass,另一個叫做AGenericClass <float> .NestedNonGenericClass。 實際上,就像你明確指定嵌套類也是通用類一樣。 如果您希望嵌套類適應泛型類型,則此行為非常有用。
但是,我發現我不能再以與普通類相同的方式使用嵌套類了。 我不記得確切的例子了,我很抱歉,但是我知道,一旦我不得不將一個類移出一個泛型,以便我可以按照預期從代碼中的其他地方使用它。 它違背了我一直用於嵌套類的常用模式,因此我不喜歡它,但這是唯一的方法。 所以我可以理解你是否可能不同意這樣做的方式,但說實話,我認為它的方式是最清晰的方式。 我的意思是,對於您和編譯器來說,如果您將嵌套類移到外部並將其作為常規類,那么您不希望編譯器將其生成為泛型。 我不認為他們可以改善這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.