属性索引器,默认值为0(零)

时间:2013-05-16 13:52:42

标签: c# .net properties enums indexer

使用属性索引器(C#)时发现了一种奇怪的行为。

考虑以下计划:

public class Program
{
    public static void Main(string[] args)
    {
        CustomMessageList cml = new CustomMessageList
        {
            new CustomMessage(), // Type1 
            new CustomMessage(), // Type1
            new CustomMessage(), // Type1
            new CustomMessage(), // Type1
            new CustomMessage(), // Type1
            new CustomMessage()  // Type1
        };

        // Empty
        IEnumerable<CustomMessage> x1 = cml[MessageType.Type2];

        // Contains all elements (6)
        IEnumerable<CustomMessage> x2 = cml[0]; // MessageType.Type1 ????

        // Does not compile!
        IEnumerable<CustomMessage> x3 = cml[1]; // NOT MessageType.Type2 ????
    }
}

public class CustomMessageList : List<CustomMessage>
{
    public IEnumerable<CustomMessage> this[MessageType type]
    {
        get { return this.Where(msg => msg.MessageType == type); }
    }
}

public class CustomMessage
{
    public MessageType MessageType { get; set; }
}

public enum MessageType
{
    Type1,
    Type2,
    Type3
}

为什么在使用默认索引器(x2变量)时会得到所有结果?

似乎int参数(0)自动转换为枚举类型(Type1)。这不是我所期待的......

提前感谢您的解释!

2 个答案:

答案 0 :(得分:10)

C#规范声明0(和零)隐式地可转换为任何枚举类型:

  

6.1.3 隐式枚举转换允许将decimal-integer-literal 0转换为任何枚举类型以及其基础类型为枚举类型的任何可空类型。

如果没有使用值明确指定枚举,则它们为0..n,因此Type1在您的情况下为0。此行为与属性索引器无关。

由于零是唯一存在的隐式转换,因此编译正常:

IEnumerable<CustomMessage> x2 = cml[0];

但是这不会编译,因为1:

没有隐式转换
IEnumerable<CustomMessage> x2 = cml[1];

在这种情况下,您需要显式转换值:

IEnumerable<CustomMessage> x2 = cml[(MessageType)1]; //Compiles fine

答案 1 :(得分:-1)

这是因为MessageType枚举实际上是整数,而Type1枚举值是零。试试这个:

public enum MessageType
{
    Type1 = 1,
    Type2,
    Type3
}