簡體   English   中英

為什么泛型結構不能具有在 C# 中指定泛型類型的靜態成員?

[英]Why can't generic structs have static members which specify the generic type in C#?

如果這是重復的,請道歉! 我四處搜索,但找不到解釋。 一旦我嘗試實例化這個結構,下面的玩具示例就會給我一個 TypeLoadException。 如果我使用類,或者不在靜態成員中指定泛型類型(將其保留為 T),它就可以正常工作。

public struct Point<T>
{
    static Point<int> IntOrigin = new Point<int>(0, 0);

    T X { get; }
    T Y { get; }

    public Point(T x, T y)
    {
        this.X = x;
        this.Y = y;
    }
}

我比較復雜的真實情況歸結為這樣的事情,所以我真的很想了解它為什么會發出 TypeLoadException。

Github 上的這條評論另一條評論最接近於解決當前的事態,指出為什么不允許這種自引用結構定義,並且在可預見的未來可能不會。

甚至靜態成員也需要先初始化類型,然后才能將其包含在類型布局中,但是類型初始化需要初始化該靜態成員。 這個初始化依賴循環創建了導致運行時異常的 Catch-22。

根據這個評論,.NET Core 可以很好地使用這種模式。 但是當我在 .NET Core 項目中嘗試您的示例時,我發現了同樣的失敗。 因此,要么該評論有誤,要么實例成員場景與您的靜態成員場景之間存在一些細微差別(除此之外,我沒有費心進行進一步調查)。

有趣的是,dotNETFiddle.net 上使用的編譯器會發出編譯時錯誤, “結構體成員‘struct2 字段’類型為‘struct1’導致結構體布局中出現循環” 我不知道為什么 Visual Studio 編譯器似乎不再產生這個錯誤(在 2017 和 2019 年檢查過)。 這對我來說似乎是另一個錯誤。 但是 Github 上圍繞這個問題的討論似乎接受了代碼在技術上是有效的(即根據 C# 規范),所以可能在某個時候有意識地決定刪除編譯器錯誤,並讓 CLR 在運行。

請注意,錯誤參考頁面中的建議建議更改為class而不是struct 當然,這在使用struct情況下通常是不可行的; 擁有值類型可能很重要。 但是,在您的具體示例中,實際上有一個基於該想法的簡單解決方法。 由於您的字段不是struct實例的實際布局的一部分,您可以將其移動到專門用於此類值的靜態類。 例如:

public struct Point<T>
{
    public static class Constants
    {
        static Point<int> IntOrigin = new Point<int>(0, 0);
    }

    T X { get; }
    T Y { get; }

    public Point(T x, T y)
    {
        this.X = x;
        this.Y = y;
    }
}

然后,而不是(例如) Point<double>.IntOrigin ,您需要使用Point<double>.Constants.IntOrigin 由於每種類型的類型初始化都可以獨立完成,因此不會出現初始化中的循環,代碼運行良好。

暫無
暫無

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

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