2012-06-21 46 views
1

我有一個必須實現以下特性使用接口類型爲通用

public ICollection<IType> Items 
{ 
    get { return this.items;} 
} 

我的問題是如何實現這個時候this.items類型是List<MyType>其中MyType實現IType類。我必須保證以下幾點:

    是可以避免的,如果可能的
  1. 這個類可以在內部處理的this.items元素作爲其具體類型
  2. 列表的不必要的枚舉
  3. 外部呼叫者可以添加和刪除元素到這個集合

在此先感謝。

+3

要求(2)和(3)是矛盾的。你不知道調用者要添加到集合中的具體類型,那麼你怎樣才能把它們作爲一種特定的類型來對待呢? –

+3

如果你期望項目是特定類型的,允許外部類添加項目是危險的 - 當你將它們全部視爲貓時,你不會希望有人爲你的動物集合添加一條狗:-) – Cameron

+0

@PaulPhillips - 這是一個好點。我可能需要重新考慮這是如何設計的。 –

回答

1

ItemsIEnumerable<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 { } 
1

就像保羅所說的,你不能同時擁有#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; 
    } 
} 
1

正如在評論這個問題由@PaulPhillips指出:

要求(2)和(3)是矛盾的。

一種方法是的Items類型更改爲IEnumerable<IType>並有ICollection<MyType>另一個屬性。這將意味着一些重新設計,但顯然我無論如何都在討論這個錯誤。

謝謝!

1

要麼,如果你想公開爲ICollection<IType>,從而使外部呼叫者添加ITypes不在MyTypes聲明this.itemsList<IType>

這樣的內部工作,對列表中的項目

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 
} 

OR

聲明公共財產

public ICollection<MyType> Items { get return this.items; } } 

,從而允許外部呼叫者添加MyType類型的唯一項目。

我很抱歉,但你不能滿足條件(2)和(3)在同一時間


UPDATE

另一種選擇是隻允許外部呼叫者獲得的物品該列表但不添加項目,通過使用只有一個getter的索引器。

public IType this[int i] 
{ 
    get { return this.items[i]; } 
} 

外部呼叫者可再接入的項目,如本

var obj = new ClassImplementingThisStuff(); 
int i = 5; 
IType x = obj[i]; 

另外添加計數屬性

public int Count { 
    get { return this items.Count; } 
} 

這種解決方案避免了不必要的枚舉。

0

我覺得這個是可能是一個不好的設計註釋的點是有效的,但你仍然可以做這樣的事情,並逃脫它:

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); 
} 

建議你重新考慮你的儘管如此。