【问题标题】:Property indexer with default 0 (zero) value具有默认 0(零)值的属性索引器
【发布时间】:2013-05-16 13:52:42
【问题描述】:

我在使用属性索引器 (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)。这不是我所期待的......

提前感谢您的解释!

【问题讨论】:

    标签: c# .net properties enums indexer


    【解决方案1】:

    C# 规范声明 0(并且只有零)隐式可转换为任何枚举类型:

    6.1.3 隐式枚举转换允许将十进制整数文字 0 转换为任何枚举类型和任何其基础类型为枚举类型的可空类型。

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

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

    IEnumerable<CustomMessage> x2 = cml[0];
    

    但这不会编译,因为 1 没有隐式转换:

    IEnumerable<CustomMessage> x2 = cml[1];
    

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 这不会改变 OP 示例中的任何内容。文字 0 仍可转换为该枚举类型。
      • 它仍然可以转换,但 x2 变量至少会有预期的结果
      • @Servy 问题不是为什么将零转换为枚举,而是为什么 x2 包含 6 个元素。答案是因为零被转换为枚举并且枚举定义了零值。由于第一个原因内置于 C# 中,因此无法修改。但是另一个可以 - 只需让 enum 从 1 开始就可以了。我还没有运行代码,但我希望变量 x2 在此修改后包含零个元素。
      • @sysexpand "The question is not why zero gets converted to enum" 哦,真的,"It seems that the int parameter (0) is automatically converted to the enum type (Type1). This is not what I was expecting...." 这似乎正是他的问题是什么。
      • @Servy 请专注于这个问题。值 0 转换为枚举类型 MessageType,但转换为一个非常特殊的值 Type1。这仅是因为值 Type1 的基础整数值为零。当 enum 被声明为从 1 开始时,就没有办法将零转换为 MessageType.* 来代替 * 的任何东西。还有一件事:列表应该填充对象 new CustomMessage() { MessageType = MessageType.Type1 }。另一个添加 - 代码确实编译,我已经尝试过了,并在 x2 中返回 0 个元素,正如我预测的那样。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-17
      • 2011-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多