문제

I discovered a strange behavior when using property indexer (C#).

Consider the following program:

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
}

Why do I get all results back when using the default indexer (the x2 variable)?

It seems that the int parameter (0) is automatically converted to the enum type (Type1). This is not what I was expecting....

Thanks in advance for the explanations!

도움이 되었습니까?

해결책

The C# specification states that 0 (and only zero) is implicitly convertible to any enum type:

6.1.3 An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any enum-type and to any nullable-type whose underlying type is an enum-type.

If you don't explicitly assign your enumerations with values, they are 0..n, so Type1 is 0 in your case. This behavior has nothing to do with property indexers.

Since zero is the only implicit conversion that exists, this will compile fine:

IEnumerable<CustomMessage> x2 = cml[0];

But this will not compile because there is no implicit conversion for 1:

IEnumerable<CustomMessage> x2 = cml[1];

In that case, you would need to explicitly convert the value:

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

다른 팁

That is because MessageType enum is in fact integer and Type1 enumeration value is zero. Try this:

public enum MessageType
{
    Type1 = 1,
    Type2,
    Type3
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top