[英]For C#, is it possible to specify type constraints in an instance declaration of a generic class?
我想帶兩個具有共享層次結構的對象,它們都實現一個接口,並將它們放在一個容器中,例如List,它通常采用單個類型的參數。 我在這個問題中使用了非編譯代碼,因為我找不到C#的一個功能,它可以讓我在編譯時做我想問的事情。
所以,設置如:
public class DataObject
{
int property;
}
public interface IWriteData
{
void WriteData();
}
public class A : DataObject, IWriteData, IDoSomethingElseA
public class B : DataObject, IWriteData, IDoSomethingElseB
和代碼:
var x = new A();
var y = new B();
List<T> where T : (DataObject, IWriteData) mySharedContainer = new List<T>;
T.Add(x);
T.Add(y);
上面的列表聲明行不起作用,但是我能想到的最接近我的目標。 我的預感是,這不是目前能夠完成的事情,我需要:
但是,我會非常高興地發現其他情況。 在考慮它時,我看不出任何直接的理由,理論上,編譯器不能在該行說“好吧,從現在開始我將檢查添加到此列表的所有內容是否繼承自該類並實現這些接口“。
謝謝!
您想要的功能稱為交集類型 ,C#對交集類型的支持非常非常有限。 實際上只有一種方法可以指定類似的類型限制,它是這樣的:
class C
{
public static void M<T>(T t) where T : DataObject, IWriteData
{
List<T> myList = new List<T>() { t };
// With this restriction we can make both these conversions:
IEnumerable<DataObject> iedo = myList; // Legal
IEnumerable<IWriteData> iewd = myList; // Legal
}
}
T
僅限於在實現IWriteData
的類型和擴展DataObject
的類型的交 IWriteData
的類型。
但這並不能解決你遇到的問題。 在這個解決方案中,我們可以調用M<A>
或M<B>
並獲得T
的列表,其中T
絕對是DataObject
和IWriteData
。 但你必須說出 T
是什么。 T
可以是A
或B
,但T
不能是“ A
或B
”。 (並且“A或B”將是聯合類型 。)
在考慮它時,我看不出任何直接的理由,理論上,編譯器無法在該行說“好吧,從現在開始我將檢查添加到此列表的所有內容是否繼承自該
對象類並實現這些接口“。
( 對象是類的實例;類擴展類,而不是對象。)
你是對的; 沒有理論上的理由。 有些語言支持union和intersection類型; Hack,我現在使用的語言,就是這樣一種語言。 TypeScript也支持這種類型的輸入。 但是C#不是其中之一,對不起。
這是不可能的。
在C#中,您只能為字段,方法,屬性等指定一種類型。這就是泛型無法執行此操作的原因。 泛型只是編譯為您使用的每種類型組合的單獨的類/方法。
您必須在類中實現接口或繼承接口,以便您只需指定一個接口。
我並不是百分之百地確定你想要達到的目的但是聲明
List<T> where T : (DataObject, IWriteData) mySharedContainer = new List<T>;
由於一些原因是不可能的。 首先,我們不能指定內聯泛型,如果我們可以, List<T>
類型不接受兩個類型參數。
但是,正如我所看到的,你可以有效地創建另一個界面
public interface ISharedObject
{
int Property { get; set; }
void WriteData();
}
然后,您只需將您的類修改為:
public class A : DataObject, IWriteData, ISharedObject, IDoSomethingElseA
{
public void WriteData();
}
public class B : DataObject, IWriteData, ISharedObject, IDoSomethingElseB
{
public void WriteData();
}
因此,接口ISharedObject
同時具有Property
和WriteData()
簽名。 DataObject
實現了Property
(注意我將其更改為屬性而不是字段)。 然后接口IWriteData
定義WriteData
方法的契約。 因此兩者都會編譯。
現在你有一個類型的參數,可以調用
var x = new A();
var y = new B();
var list = new List<ISharedObject>();
list.Add(x);
list.Add(y);
如果我誤解了您的要求,請事先提前申請。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.