Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#使用泛型类型重写实现接口_C#_Generics_Interface_Implements - Fatal编程技术网

C#使用泛型类型重写实现接口

C#使用泛型类型重写实现接口,c#,generics,interface,implements,C#,Generics,Interface,Implements,为了简化我的问题,我使用IList和IList作为示例。 由于IList声明了一个方法Add(object value)和IList声明了一个方法Add(T value)。我的新类必须有两种实现方法 class myList<T> : IList<T>, IList { public void IList.Add(object value) { this.Add(value as T); } public void Add(T value) {

为了简化我的问题,我使用
IList
IList
作为示例。 由于
IList
声明了一个方法
Add(object value)
IList
声明了一个方法
Add(T value)
。我的新类必须有两种实现方法

class myList<T> : IList<T>, IList
{
  public void IList.Add(object value)
  {
    this.Add(value as T);
  }
  public void Add(T value)
  {...}
}
类myList:IList,IList
{
public void IList.Add(对象值)
{
此。添加(值为T);
}
公共无效添加(T值)
{...}
}

有可能避免这种“无意义”的复制吗?

IList集合存储
对象
实例,但
IList
存储特定类型的实例。
Add
方法对
IList
IList
接口具有不同的签名。因此,您需要声明这两种方法。

不,这是不可避免的。因为这违反了接口的原则。考虑一个只与IList一起工作的客户端程序。这个程序希望现在就使用你的类,这当然是可行的,因为你实现了IList。因此,他称这种方法为:

public void IList.Add(object value)
{
  this.Add(value as T);
}
如果你不实施,现在该怎么办?当然,您可以调用
Add
,但是如果有许多类实现了IList,并且您在IList接口上调用Add方法以在引擎盖下使用多态性,那么这将不再有效


C#在这里是严格的,这是有充分理由的,就像我所知道的任何其他具有接口概念的语言一样。

也许你应该避免实现非泛型的
IList
,因为它违反了坚实且更精确的Liskov替换原则。当泛型不可用时,它是.NET1的遗留接口。如果您处理的是遗留代码,那么它可能是必要的

如果您必须实现Hans所说的IList
IList
,请使用快速失败的实现:当列表中不允许提供的对象时抛出异常

void IList.Add(object value)
{
  this.Add((T)value);
}

如果您正在实现一个接口(或一组接口),它指示您同时需要这两个接口,那么您需要声明这两个接口。时期通常,您可以实现其中一个,然后让其他所有人调用第一个。您同时实现了
IList
IList
,因此需要重复。它们不是同一个接口——一个处理通用实现,另一个处理标准对象。对于大多数IEnumerable派生接口,你也会得到同样的结果,我认为这是由于枚举数的缘故,但我可以马上记住。只要你试图复制15年前的错误,就不会。代码是错误的,它必须使用这个。添加((T)值)。如果你在寻找减少复制的东西,请查看继承,而不是接口。接口只是一个契约,类必须遵循它才能以某种方式使用它。谢谢forks。我必须使用非泛型类型接口,因为对象类型也实现多个接口,并且需要是一个没有基类可调用的类,并且它们是在运行时确定的。这是一个非常特殊的情况。