C# 实现具有泛型类型覆盖的接口
C# implementing interfaces with generic type overrides
为了简化我的问题,我使用 IList
和 IList<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
方法对 IList
和 IList<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);
}
为了简化我的问题,我使用 IList
和 IList<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
方法对 IList
和 IList<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);
}