如何解决 Generic.IList<T>.this[] 和 IList.this[] 之间的调用歧义?
题
我有一个集合,它实现了扩展 IList<T> 和 List 的接口。
public Interface IMySpecialCollection : IList<MyObject>, IList { ... }
这意味着我有两个版本的索引器。
我希望使用通用实现,因此我通常实现该实现:
public MyObject this[int index] { .... }
我只需要 IList 版本进行序列化,因此我显式实现它,以将其隐藏:
object IList.this[int index] { ... }
但是,在我的单元测试中,以下内容
MyObject foo = target[0];
导致编译器错误
呼叫在以下方法或属性之间含糊不清
我对此感到有点惊讶;我相信我以前做过并且效果很好。我在这里缺少什么?如何让 IList<T> 和 IList 在同一接口中共存?
编辑 IList<T> 确实 不是 实现IList,我 必须 实现 IList 进行序列化。我对解决方法不感兴趣,我想知道我错过了什么。
再次编辑: :我不得不从界面中删除 IList 并将其移到我的班级上。我不想这样做,因为实现该接口的类最终将被序列化为 Xaml,这需要集合来实现 IDictionary 或 IList...
解决方案
你不能这样做
public interface IMySpecialCollection : IList<MyObject>, IList { ... }
但是您可以对类执行您想要的操作,您需要显式地实现其中一个接口。在我的示例中,我明确了 IList。
public class MySpecialCollection : IList<MyObject>, IList { ... }
IList<object> myspecialcollection = new MySpecialCollection();
IList list = (IList)myspecialcollection;
您是否考虑过让 IMySpecialCollection 实现 ISerializable 来进行序列化?支持多种集合类型对我来说似乎有点错误。您可能还想考虑将 IList 转换为 IEnumerable 进行序列化,因为 IList 仅包装 IEnumerable 和 ICollection。
其他提示
这是一个骗局 我的问题在这里
总而言之,如果你这样做,就可以解决问题:
public Interface IMySpecialCollection : IList<MyObject>, IList
{
new MyObject this[int index];
...
}
不幸的是,您不能声明具有相同参数列表的两个索引器。以下段落摘自此处 C# 编程指南 - 使用索引器“备注”部分:
索引器的签名由其形式参数的数量和类型组成。它不包括索引器类型或形式参数的名称。如果您在同一类中声明多个索引器,它们必须具有不同的签名。
如果您希望使用第二个索引器,则必须声明一组不同的参数。
将您的通用实现更改为...
T IList<T>.this[int index] { get; set; }
这明确说明了哪个“这个”是哪个。
List<T> 隐含 IList,因此在同一个类中使用两者不是一个好主意。