不同泛型类型中的非泛型成员是否相同

Doest non-generic members in different generic types are same or not

public sealed class Reference<T>
{
    private static ulong maxID = 0;
    private ulong id = maxID++;
    public ulong LongID => this.id;
    public Reference() { }
    public bool Equals(T? other)
        => other?.Reference.id == this.id;
    public bool Equals(Reference<T>? other)
        => other?.id == this.id;
    public override bool Equals(object? obj)
        => obj is T it ? Equals(it) : obj is Reference<T> rf ? Equals(rf) : false;
    public override int GetHashCode() => HashCode.Combine(this.id);

    public static bool operator ==(Reference<T>? left, Reference<T>? right)
        => left?.Equals(right) ?? false;

    public static bool operator !=(Reference<T>? left, Reference<T>? right)
        => !(left == right);

    public override string ToString() => $"Reference<{typeof(T).Name}> ({this.id})";
}

在这段代码中,我有 class Reference<T> 和静态字段。 如果我创建新实例,他将获得个人 ID
new Reference<T>(); ID 等于 0
new Reference<T>(); id 等于 1
在 dotnet 中,当您在引擎盖下使用通用类型时创建了新的非通用类型
我认为 Reference<T>.maxID 的值为 2 而 Reference<T2>.maxID 为 0
但是这个字段是非泛型的,很可能字段在不同的泛型类型中是相同的

是的,当您使用带有新泛型参数的泛型类型时,会在后台创建新的 non-generic 类型并且所有 non-generic 成员也会复制

new Reference<Int32>(); id 为 0
new Reference<UInt32>(); id 为 0,导致其类型不同

如果我想要不同的结果,我应该使用 public|内部静态字段 maxID 和使用他

来自 C# 6 规范草案的部分 8.4.3 Open and closed types

Each closed constructed type has its own set of static variables, which are not shared with any other closed constructed types. Since an open type does not exist at run-time, there are no static variables associated with an open type. Two closed constructed types are the same type if they are constructed from the same unbound generic type, and their corresponding type arguments are the same type.

因此 Reference<T>.maxID 中的每个不同的 T 都会有不同的 maxID

In dotnet when you use generic type under hood created new non-generic type

请注意,这里有一个小警告。取决于所使用的泛型类型参数(特别是如果它们是 reference or value types) CLR implementation of C# can behave differently in terms of method compilation. To prevent generic code bloat for reference types methods code is reused while for every value type new implementation will be compiled. See .NET Generics and Code Bloat 文章。