我应该避免泛型类型中的嵌套类型吗?

And*_*ren 7 .net c# generics

如果我实现了一个可能有大量类型参数实例化的泛型类型,我应该避免(对于JIT性能/代码大小等原因)有多个嵌套的非泛型类型吗?

例:

public class MyGenericType<TKey, TValue>
{
    private struct IndexThing
    {
        int row; int col;
    }

    private struct SomeOtherHelper
    {
        ..
    }

    private struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>> { }

}
Run Code Online (Sandbox Code Playgroud)

同样有效的替代方法是在外部使用非泛型类型,但是它们会污染命名空间.有最好的做法吗?

public class MyGenericType<TKey, TValue>
{
    private struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>> { }
}

internal struct IndexThingForMyGenericType
{
   int row; int col;
}

internal struct SomeOtherHelper
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

Sri*_*vel 6

在C#中,泛型类型的每个嵌套类型本质上都是通用的.编译器也会将嵌套类型设置为通用类型(我们不知道).有关详细信息,请参阅此文章.

虽然泛型分享了本次访谈中解释的引用类型的JIT代码,但与非泛型类相比,它有一些开销.每种值类型都有自己的JIT代码.

  • 如果类型仅在泛型类中使用 - 作为私有嵌套类型更有意义.

  • 如果在其他地方使用该类型,那么理想情况下它应该是非嵌套类型(作为内部).

也就是说,如果您的嵌套类型T在这种情况下不使用Type参数,则它不需要是泛型类型的嵌套类型,因此它也变为泛型类型.

大多数情况下它应该无关紧要但是如果您关注在运行时创建的许多类型,您可以重构您的泛型类型以具有非泛型基类,该基类充当嵌套类型的容器类型并公开嵌套类型作为保护.

public class NonGenericBase
{
    protected struct IndexThing
    {
        int row; int col;
    }

    protected struct SomeOtherHelper
    {
        ..
    }
}

public class MyGenericType<TKey, TValue> : NonGenericBase
{
    private struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>> { }

}
Run Code Online (Sandbox Code Playgroud)

这样您就可以共享相同的嵌套类型.没有运行时开销.每个类型参数没有单独的类型.现在typeof(MyGenericType<int, string>.SomeOtherHelper)将等于typeof(MyGenericType<long, bool>.SomeOtherHelper).