考虑以下代码:
namespace MyApp
{
using System;
using System.Collections.ObjectModel;
class Program
{
static void Main(string[] args)
{
var col = new MyCollection();
col.Add(new MyItem { Enum = MyEnum.Second });
col.Add(new MyItem { Enum = MyEnum.First });
var item = col[0];
Console.WriteLine("1) Null ? {0}", item == null);
item = col[MyEnum.Second];
Console.WriteLine("2) Null ? {0}", item == null);
Console.ReadKey();
}
}
class MyItem { public MyEnum Enum { get; set; } }
class MyCollection : Collection<MyItem>
{
public MyItem this[MyEnum val]
{
get
{
foreach (var item in this) { if (item.Enum == val) return item; }
return null;
}
}
}
enum MyEnum
{
Default = 0,
First,
Second
}
}
我很惊讶地看到以下结果:
1) Null ? True
2) Null ? False
我的第一个期望是,因为我传递了一个int
,所以应该使用默认索引器,并且第一次调用应该成功。
相反,似乎enum
总是调用期望 an 的重载(即使将 0 转换为 int 时也是如此),并且测试失败。
- 有人可以向我解释这种行为吗?
- 并给出一个解决方法来维护两个索引器:一个按索引,一个用于枚举?
编辑:一种解决方法似乎是将集合转换为集合,请参阅此答案。
所以:
- 为什么编译器选择最“复杂”的重载而不是最明显的重载(尽管它是继承的)?索引器是否被视为本机 int 方法?(但没有警告您隐藏父索引器的事实)
解释
使用这段代码,我们面临两个问题:
- 0 值始终可以转换为任何枚举。
- 运行时总是在挖掘继承之前检查底层类,因此选择了枚举索引器。
有关更精确(和更好的公式化)的答案,请参阅以下链接: