簡體   English   中英

將方法類型參數約束為類通用類型的基礎

[英]Constrain method type argument to be base of class generic type

我想確保方法類型參數是類通用類型的基本類型,因此首先我自然地這樣寫:

public class FivePM<T> {
    public void drink<M>(M x) where T : M {}
}

是否有任何特定原因導致其無法正常工作?

背景

我寫了容器類Bag<B>來存儲在不同實例之間共享的項目,因此,如果將一個項目添加到另一個袋子中,則會自動將其從一個袋子中刪除。 這是由BagSet<BT>在內部完成的,該BagSet<BT>保存普通物品的袋子。 我希望袋子通用類型是集合中項目的最低通用類型,但我不希望constrian B完全是BT而是任何派生類型。 我設法使袋子的類型安全的公共接口滿足了我的要求,但是由於通用約束的限制,袋子的構造看起來很尷尬,我不能使用列表初始化程序:

BagSet<object> bset = new BagSet<object>();
Bag<int> suitcase = bset.newBag<int>();

public class BagSet<T> : BagSetBase {
    public Bag<B> newBag<B>(string name = null, params B[] items) where B : T {
        var b = new Bag<B>(this, name);
        for (int i = 0; i < items.Length; i++) b.Add(items[i]);
        return b;
    }
}

通用約束是否有一天會得到改善? 也許我應該等待,然后再廣泛地做這些事情。

使用您的真實代碼,如果使class Bag成為兩種類型並處理繼承要求,該怎么辦-畢竟,您不必在BagSet關心它:

public class BagSet<T> {
    public Bag<B, T> newBag<B>(string name = null, params B[] items) where B : T {
        var b = new Bag<B, T>(this, name);
        for (int i = 0; i < items.Length; i++) b.Add(items[i]);
        return b;
    }
}

public class Bag<B, T> where B : T {
    BagSet<T> common;
    string bsname;

    public Bag(BagSet<T> bs, string name) {
        common = bs;
        bsname = name;
    }
    public void Add(B item) {
    }
}

然后,您可以像這樣聲明它們:

var bset = new BagSet<object>();
var suitcase = bset.newBag<int>();

是否有任何特定原因導致其無法正常工作?

如果您的意思是說這種約束沒有道理是合乎邏輯的 ,那就沒有。 這是一個完全明智的約束,並且有些語言支持這種約束。 以Java為例。 和斯卡拉。

如果您的意思是為什么在C#中不起作用,那很簡單。 沒有人在C#中實現該功能。 為了使功能可以在C#中工作,必須有人考慮,設計,編寫規范,實施規范,編寫測試,然后將其交付給客戶。 在這些必要步驟中,只有第一個發生了。

通用約束是否有一天會得到改善?

要求對未來進行預測的問題不在Stack Overflow上的話題了。 我們沒有能力可靠地預測未來。

如果您希望此功能成為C#的未來版本,請考慮在github論壇上倡導該功能。

我認為您也許可以使此工作正常:

public class FivePM<T, M> where T : M 
{
    public void drink(M x) 
}

但話又說回來,您的問題使我感到困惑,並且已經過了午夜,所以我可能錯了,我可能會誤解了這個問題...。也許不是嗎?

暫無
暫無

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

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