C# 实现具有泛型类型覆盖的接口

C# implementing interfaces with generic type overrides

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

class myList<T> : IList<T>, IList
{
  public void IList.Add(object value)
  {
    this.Add(value as T);
  }
  public void Add(T value)
  {...}
}

是否可以避免这种"meaningless"复制?

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

不,你无法避免这一点。因为这会违反接口原则。考虑一个只与 IList 一起工作的客户端程序。该程序现在想使用您的 class,这当然有效,因为您实现了 IList。所以他调用方法:

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

如果您不执行此操作,现在会发生什么?当然,您可以改为调用 Add<T>,但是如果有许多 class 实现 IList 并且您在 IList 接口上调用 Add-Method 以在幕后使用多态性,这将不再起作用。

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

也许你应该避免实现非泛型 IList 因为它违反了 SOLID,更准确地说是 Liskov 替换原则。当泛型不可用时,它是 .Net 1 的遗留接口。好吧,如果您正在处理遗留代码,那可能是必要的。

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

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