[英]Using Interface Type as generic
我有一個必須實現以下屬性的類
public ICollection<IType> Items
{
get { return this.items;}
}
我的問題是當this.items
的類型是List<MyType>
時,如何實現這一點,其中MyType
實現了IType
。 我需要確保以下內容:
this.items
的元素視為其具體類型 提前致謝。
就像保羅提到的那樣,你不能同時擁有#2和#3。 您必須選擇其中一個,或將具體類型暴露給外部呼叫者。 但是,根據您的實際需求,您最好的選擇是將您的集合作為List存儲在內部,並在需要按具體類型獲取成員時使用方法。 像這樣的東西:
private List<IType> items = new List<IType>();
private TType GetItem<TType>(int index)
where TType : IType
{
return (TType)items[index];
}
public ICollection<IType> Items
{
get
{
return this.items;
}
}
正如@PaulPhillips在對這個問題的評論中指出的那樣:
要求(2)和(3)是矛盾的。
一種方法是將Items
的類型更改為IEnumerable<IType>
並具有ICollection<MyType>
另一個屬性。 這將意味着一些重新設計但顯然我無論如何都要犯這個錯誤。
謝謝!
無論是聲明this.items
作為一個List<IType>
如果你想公開為ICollection<IType>
從而允許外部呼叫者添加ITypes
不在MyTypes
。
在列表中的項目內部工作
var myObj = this.items[i] as MyType;
if (myObj == null) {
work with this.items[i] and treat it as a IType
} else {
work with myObj which is a MyType
}
要么
將公共財產聲明為
public ICollection<MyType> Items { get return this.items; } }
因此允許外部調用者只添加MyType
類型的項目。
對不起,但你不能同時滿足條件(2)和(3)
UPDATE
另一種選擇是僅允許外部呼叫者通過使用僅具有吸氣劑的索引器來獲取列表中的項目而不是添加項目。
public IType this[int i]
{
get { return this.items[i]; }
}
然后外部呼叫者可以訪問這樣的項目
var obj = new ClassImplementingThisStuff();
int i = 5;
IType x = obj[i];
還要添加count屬性
public int Count {
get { return this items.Count; }
}
該解決方案避免了不必要的枚舉。
Items
是IEnumerable<IType>
怎么樣? IEnumerable是協變的,所以代碼只能在沒有變化的情況下工作。 另一方面,您可以使用另一種專用方法將元素添加到內部列表中。
class MainClass
{
public static void Main()
{
ShowMeHowToDoIt show = new ShowMeHowToDoIt();
show.Add( new TheType() );
foreach ( var item in show.Items )
{
Console.WriteLine( item );
}
}
}
public class ShowMeHowToDoIt
{
private List<TheType> items = new List<TheType>();
public void Add( TheType item ) { items.Add( item ); }
public IEnumerable<IType> Items
{
get { return items; }
}
}
public interface IType { }
public class TheType : IType { }
我認為關於這個可能是一個糟糕的設計的評論中的要點是有效的,但你仍然可以做這樣的事情並逃脫它:
interface IFruit
{
string Name { get; }
string SerialNumber { get; }
}
class Apple : IFruit
{
private string _serial = Guid.NewGuid().ToString();
public string Name {
get {
return "Apple";
}
}
public string SerialNumber {
get { return _serial; }
}
}
class AppleBasket : IEnumerable<IFruit>
{
private List<Apple> _items = new List<Apple>();
public void Add(Apple apple) {
_items.Add(apple);
}
public IEnumerator<IFruit> GetEnumerator() {
return _items.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return _items.GetEnumerator();
}
}
/******************/
AppleBasket basket = new AppleBasket();
Apple apple1 = new Apple();
basket.Add(apple1);
Apple apple2 = new Apple();
basket.Add(apple2);
foreach (IFruit fruit in basket) {
Console.WriteLine(fruit.SerialNumber);
}
我建議你重新考慮,雖然你的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.