C# 父非泛型接口方法的泛型接口隐藏

C# 父非泛型接口方法的泛型接口隐藏,c#,.net,C#,.net,我想用通用接口IAppcontextItem实现一个通用类AppContextItem。因为我想在不知道确切类型的情况下在列表中存储多个AppContextItems(并且我希望能够在列表中混合多个类型化的AppContextItems)。我创建了另一个非通用接口IAppContextItem。IAppContextItem的泛型实现应该隐藏非泛型字段,但不知何故它没有隐藏,因为我得到一个编译错误,告诉我需要使用返回类型对象实现元素。是不可能做我想做的事还是我做错了什么 IAppcontextI

我想用通用接口IAppcontextItem实现一个通用类AppContextItem。因为我想在不知道确切类型的情况下在列表中存储多个AppContextItems(并且我希望能够在列表中混合多个类型化的AppContextItems)。我创建了另一个非通用接口IAppContextItem。IAppContextItem的泛型实现应该隐藏非泛型字段,但不知何故它没有隐藏,因为我得到一个编译错误,告诉我需要使用返回类型对象实现元素。是不可能做我想做的事还是我做错了什么

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; }
}
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; }
    }
公共接口IAppContextItem
{
字符串键{get;set;}
对象元素{get;set;}
}
公共接口IAppContextItem:IAppContextItem
T:在哪里上课
{
新字符串键{get;set;}
新的T元素{get;set;}
}
AppContextItem.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; }
}
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; }
    }
公共类AppContextItem:IAppContextItem,其中T:class
{
私有字符串密钥=string.Empty;
私有T元素;
公共字符串密钥
{
获取{return key;}
设置{key=value;}
}
公共T元素
{
获取{return element;}
设置{element=value;}
}

您必须同时实现
T元素
T和
对象元素
属性。对象元素的实现如下所示:

object IAppContextItem.Element
{
   get; set;
}
然后可以将其强制转换到正确的界面:

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

这句话表明了你的误解:

IAppContextItem的泛型实现应该隐藏非泛型字段,但不知何故它没有隐藏,因为我得到一个编译错误,告诉我需要使用返回类型对象实现元素

接口是契约;它表示“此接口的实现需要提供以下方法和属性…”。通过继承隐藏方法或属性既不能满足契约的该部分,也不能消除契约对实现者的要求。


合同规定,一个实现需要提供四个属性。其中一些属性与其他属性具有相同的名称,但这并不能消除您提供合同中描述的每个属性的要求。其中两个属性“更可见”除此之外,其他两个属性并没有改变契约需要四个属性的事实。您仍然需要实现所有四个属性;它们的可见性根本不包含在其中。

Wouter de Kort的回答掩盖了一个重要的问题:如果您希望两个元素属性都引用同一个对象,那么您不能这样做:

object IAppContextItem.Element
{
    get; set;
}
如果这样做,您会发现您已经为接口的
元素
属性创建了一个自动属性,该属性的值独立于
T
类型的元素属性。相反,您应该执行以下操作:

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

我不明白你为什么要实现这两个接口,因为泛型接口就足够了。唯一的区别是元素属性的类型;非泛型接口没有任何好处。你是对的,请参阅我对Wouter de Kort答案的评论。这解决了我的问题谢谢你!感谢所有与类似问题斗争的人。我按照jmpcm的建议删除了通用接口,我按照Wouter de Kort的建议向AppContextItem添加了对象IAppContextItem.Element。别忘了在IAppContextItem.Element的实现中仍然填充getter和setter的值。否则,将AppContextItem强制转换为IAppContextItem并希望访问该值。