【发布时间】:2011-11-20 10:28:34
【问题描述】:
考虑以下代码:
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 的重载(即使将 0 转换为 int 时也是如此),并且测试失败。
- 谁能向我解释一下这种行为?
- 并提供一种解决方法来维护两个索引器:一个按索引,一个用于枚举?
编辑:一种解决方法似乎是将集合转换为集合,请参阅this answer。
所以:
- 为什么编译器选择最“复杂”的重载而不是最明显的重载(尽管它是继承的)?索引器是否被视为本机 int 方法? (但没有警告您隐藏父索引器)
说明
使用这段代码,我们面临两个问题:
- 0 值始终可以转换为任何枚举。
- 运行时总是从检查底层类开始,然后再挖掘继承,因此选择了枚举索引器。
如需更精确(和更好表述)的答案,请参阅以下链接:
- original answer James Michael Hare
- sum up Eric Lippert
【问题讨论】:
标签: c# enums overloading indexer