簡體   English   中英

c# 通用約束哪里不是 class?

[英]c# generic constraint where is not class?

是否有泛型的 where 子句確定 T 是原始類型?

 void Method<T>(T val) where T : primitive

案件:

有一種用 C 編寫的功能語言,它以原始的非托管 blitable 類型為食,或者可以很容易地推入原始類型的東西(例如,沒有小時/分鍾/秒的日期可以推入一個 int 等)。最初的計划是利用 GPU。雖然沒有這樣做。 到目前為止,C# 在其協調員角色中表現良好。 我傾向於認為模式的家居住在 C#。嚴格來說這並不正確,但這個想法很好地服務於項目。

我喜歡 OO,但當談到功能性想法時,我想將這些想法限制在該領域支持的類型上。 有趣的是,我仍然依靠 C# 來幫助我保持條理和紀律。 我認為這沒有改變。


還有其他原因可以解釋為什么對約束進行更詳細的說明對我來說是一件好事。

順便說一句:resharper 建議我嘗試了一段時間的顯式接口。 我真的很喜歡這種表示法……並且約束也可以與界面一起使用。 好的。 然而,我在 S/O 上看到了 Jon Skeet 關於這個混亂的警告 inheritance。所以,回到勞動密集型運行時 AssertIsXYZ。

更進一步,對我的限制是朝着證明正確性邁出的一步(舊想法,但仍然是好想法)。 打字系統似乎可以將其中的一些推送給編譯器。 使用“where”這個詞讓人想到一個子句或短語(就像在 SQL/LINQ 中一樣)。 我並不是要求將它提升到第 n 級。 就我而言,編譯器可以做的工作越多越好。

接觸約束幫助我澄清了一些想法。 必須在那里給予信任......但遺憾的是我不得不事后評論這些限制。

我懷疑基於你對Jon的答案的評論你想要的是一種將類型參數約束為blittable類型或非托管類型的方法

“非托管類型”是一種類型,其定義排除了對垃圾收集器跟蹤的內存的任何引用; 你只能用非托管類型制作指針類型。 Blittable類型是可以從托管代碼編組到非托管代碼而不對其位進行任何修改的那些類型; 它們是非托管類型的子集。

許多人告訴我們,擁有一個將類型參數限制為非托管類型的通用約束會非常方便。 我們已經嘗試了具有此約束的C#和CLR原型,但目前還沒有計划將該功能實際放入產品中。 如果您可以描述激發功能請求的方案,那么這將有助於我們根據可能的數百個其他功能確定功能的優先級。

where T : struct

那是一樣的它是一個原始類型,請不要忘記。 它強制它成為不可為空的值類型。 那將包括,例如, Guid (不是原始的)但排除Nullable<Guid> (它既不是原始的, 也不是一個類)。

如果您可以更准確地了解您的要求,我們可能會為您提供更多幫助。

沒有! 原始類型沒有約束。

強制執行原始類型的最佳選擇如下:

void Method<T>(T val) where T:struct
{
    if (!typeof(T).IsPrimitive)
        throw new ArgumentException("Only primitive types are allowed.", "val");
}

要么

public void Method(int val)
{
    GenericMethod(val);
}

public void Method(double val)
{
    GenericMethod(val);
}

private void GenericMethod<T>(T val) where T:struct
{
}

你不能這樣做(至少目前)。 如果您希望它是值類型:

void Method<T>(T val) where T : struct

或者你可以在運行時檢查它,以確保它是真正原始的(我認為你想要int / float / etc而不是所有的值類型?)

public static class Ext
{
    public static bool IsPrimitive(this Type t)
    {
        return t == typeof(int) || t == typeof(float) 
            || t == typeof(double) || ...
    }
}

EDIT LOL剛剛發現Type中有一個名為IsPrimitive的內置屬性,這就是我要說的......

不,C#不知道任何像primitive這樣的關鍵字。

查看這篇文章: 如何定義原始類型的泛型類型限制?

我只是在這個帖子中添加一些新信息,抱歉挖掘它...

正如許多人已經回答的那樣,現在可以使用以下構造很長一段時間了:

void Method<T>(T val) where T : struct

隨着C#7.3的發布,人們可以寫:

void Method<T>(T val) where T : unmanaged

資料來源:

沒有,但你可以使用struct約束。

where T: struct

約束必須是非密封類型,因此沒有辦法將泛型約束為基本類型。

暫無
暫無

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

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