2012-02-08 52 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; 
    } 
}