V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lights
V2EX  ›  C#

请教一下 C#中枚举作为字典 key 时的行为,感觉很怪

  •  
  •   lights · 2021-02-01 19:07:25 +08:00 · 2014 次点击
    这是一个创建于 1389 天前的主题,其中的信息可能已经有所发展或是发生改变。
    using System;
    using System.Collections.Generic;
    
    namespace cSharpSolution
    {
        internal class Program
        {
            public enum AlphaEnum
            {
                A, B, C
            };
    
            public enum BetaEnum
            {
                A, B, C
            }
    
            /// <summary>
            /// 测试 c# 的 Enum 作为字典的 key 是什么?
            /// </summary>
            /// <param name="args"></param>
            private static void Main(string[] args)
            {
                var d = new Dictionary<Enum, int>();
                d[AlphaEnum.A] = 111;
                d[BetaEnum.A] = 222;
    
                Console.WriteLine($"d[AlphaEnum.A] : {d[AlphaEnum.A]} ");
                Console.WriteLine($"d[BetaEnum.A] : {d[BetaEnum.A]} ");
    
                foreach (var item in d)
                {
                    Console.WriteLine($"<{item.Key} : {item.Value} >");
                }
            }
        }
    }
    

    源码如上,拷贝到文件里可直接运行
    主要疑问在定义了一个 <Enum, int> 的字典,以 Enum 为 key 的时候
    原本以为 Enum 会转换成 int,后面的赋值会覆盖前面的赋值
    但实际上应该是转换成了 <类型+int> 的一个字符串或者怎样的东西,使得不同的 enum 类型的 “0 值” 可以作为不重复的 key
    请教一下有没有相关的介绍说明,感觉这一块是个挺奇怪的默认行为

    6 条回复    2021-02-08 11:22:28 +08:00
    yejinmo
        1
    yejinmo  
       2021-02-01 19:37:47 +08:00
    1. 所有的小写的 `enum` 都派生于大写的 `Enum`,前者是关键字,也就是你这个 `AlphaEnum` 和 `BetaEnum`,而后者是个类,派生类不同他们的 HashCode 自然不同
    2. 最后输出应该是两个 A,这是因为 `Enum` 类自带的 ToString() 方法导致的,和他们本身的值无关
    lights
        2
    lights  
    OP
       2021-02-02 09:41:41 +08:00
    @yejinmo #1
    所以 C#字典把一个对象作为 key 时,用的是 HashCode ?才知道这个说法
    lights
        3
    lights  
    OP
       2021-02-02 09:45:32 +08:00
    @yejinmo #1
    上面示例代码中的两个 Enum 用 GetHashCode() 方法返回的都是 0
    yejinmo
        4
    yejinmo  
       2021-02-02 10:37:03 +08:00
    @lights #3

    GetHashCode() 的值相等时会进一步调用 Equals() 方法
    forgottencoast
        5
    forgottencoast  
       2021-02-08 00:47:26 +08:00   ❤️ 1
    @lights 可以看看《 CLR via C#》,这本书应该都有讲。
    lights
        6
    lights  
    OP
       2021-02-08 11:22:28 +08:00 via iPhone
    @forgottencoast
    这本书排在很后面了,先看 shader,多谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3119 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 12:38 · PVG 20:38 · LAX 04:38 · JFK 07:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.