2012-02-08 53 views
2

我想實現一個泛型類AppContextItem與通用接口IAppcontextItem。因爲我想在List中存儲多個AppContextItem而不知道確切的類型(並且我希望能夠在列表中混合多個類型化的AppContextItems)。我創建了另一個非通用接口IAppContextItem。 IAppContextItem的通用實現應該隱藏非泛型字段,但它不知道,因爲我得到一個編譯錯誤,告訴我需要用返回類型對象實現Element。是不可能做我想做的或者我做錯了什麼?的母公司非通用接口方法通用接口隱藏

IAppcontextItem.cs

public interface IAppContextItem 
{ 

    string Key { get; set; } 

    object Element { get; set; } 

} 

public interface IAppContextItem<T> : IAppContextItem 
    where T : class 
{ 
    new string Key { get; set; } 
    new T Element { get; set; } 
} 

AppContextItem.cs

public class AppContextItem<T> : IAppContextItem<T> where T : class 
{ 

    private string key = string.Empty; 
    private T element; 

    public string Key 
    { 
     get { return key; } 
     set { key = value; } 
    } 

    public T Element 
    { 
     get { return element; } 
     set { element = value; } 
    } 
+1

我不明白你爲什麼實現2接口,因爲通用的就足夠了。唯一的區別是Element屬性的類型;你沒有從非通用接口獲得任何收益。 – jmpcm 2012-02-08 16:37:36

+0

你說得對,看到我對Wouter de Kort的回答的評論。 – nino 2012-02-08 16:52:38

回答

4

你必須同時實現T Elemen噸和object Element性能。對於object Element實施將看起來像:

object IAppContextItem.Element 
{ 
    get; set; 
} 

然後,您可以將它轉換爲正確的接口:

AppContextItem<MainApp> app = new AppContextItem<MainApp>(); 
IAppContextItem iapp = (IAppContextItem)app; 
object o = iapp.Element; 

這就是所謂的Explicit Interface Implementation

如果你想有一個不同的實施IAppContextItem.KeyIAppContextItem<T>.Key你可以使用這樣的顯式接口實現:

string IAppContextItem.Key 
{ 
    get { return key + "A"; } 
    set { key = value; } 
} 

string IAppContextItem<T>.Key 
{ 
    get { return key + "B"; } 
    set { key = value; } 
} 
+0

這解決了我的問題,謝謝! 對於每個人都在努力解決類似的問題。我刪除了通用接口作爲jmpcm建議,我添加對象IAppContextItem.Element作爲Wouter de Kort建議的AppContextItem。不要忘記在IAppContextItem.Element的實現中仍然會提供getter和setter的值。否則,當您將AppContextItem轉換爲IAppcontextItem並想要訪問該值時,您會遇到問題。 – nino 2012-02-08 16:49:58

4

這是表示你誤會了一句:

通用執行IAppContextItem應該隱藏非泛型字段,但它不知道,因爲我得到一個編譯錯誤,告訴我我需要用返回類型對象實現Element。

一個接口是一個合同;它說:「需要實現這個接口來提供以下方法和屬性...」。 隱藏通過繼承方法或屬性既不滿足合同的那部分,也沒有消除了合同強加於實施者的要求。

合同說的實現需要提供四個屬性。這些財產中的一些與其他財產具有相同的名稱並不以任何方式消除您提供合同所描述的每個財產的要求。這其中的兩個屬性是「更明顯」比其他兩種不改變該合同的需要四個屬性的事實。你仍然需要實現所有四個;他們的知名度根本不包括在內。

2

沃特,德科爾特的回答掩蓋了一個重要的觀點:如果你想同時元素屬性是指同一個對象,你不能做到這一點:

object IAppContextItem.Element 
{ 
    get; set; 
} 

如果你這樣做,你會發現,你已經創建了接口的Element財產,其價值是獨立於T -typed Element屬性自動屬性。相反,你應該這樣做:

object IAppContextItem.Element 
{ 
    get { return this.Element; } 
    set 
    { 
     if (!(value is T)) 
      throw // ... some exception 
     this.Element = (T)value; 
    } 
}