• 新疆花开天山南北 笑迎八方来客 2019-03-25
  • 机器人占领就业市场后:人类还能从事这些工作 2019-03-04
  • 以网络文化建设推进文化惠民 2019-03-03
  • 贸易战,只能是双输。我们是众志成城,美国却不一定。 2019-02-26
  • 辣评2016年9月最HOT 轿车获奖榜单 2019-02-22
  • 交通运输部路网中心:端午假期高速通行不免费 2019-02-18
  • 《陕西省县域经济社会发展监测考评办法》解读 2019-02-18
  • 西部网(陕西新闻网)www.cnwest.com 2019-02-13
  • 短途一日游 游客量猛增 小长假新疆接待游客353.6万人次 2019-02-13
  • 南昌重拳整治酒驾毒驾 2019-02-08
  • 女性之声——全国妇联 2019-02-08
  • 信息网络传播视听节目许可证 2019-02-03
  • 打开书籍,了解文物背后的中国温度 2019-02-03
  • 中央环保督察组:石家庄市无极县“敷衍整改” 2019-02-02
  • China Focus Dragon Boat Festival celebrated across China - Culture News - CQNEWS 2019-02-02
  • 广东南粤风釆36先7开奖: DevTips Unity C#编程优化——枚举

    151
    回复
    20120
    查看
    打印 上一主题 下一主题
      [ 复制链接 ]
    排名
    9773
    昨日变化
    1

    福建36选7和值走势图 www.00-na.com 263

    主题

    301

    帖子

    1602

    积分

    Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15

    UID
    159865
    好友
    9
    蛮牛币
    3981
    威望
    0
    注册时间
    2016-8-1
    在线时间
    626 小时
    最后登录
    2018-3-8

    蛮牛译员

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

    您需要 登录 才可以下载或查看,没有帐号?注册帐号

    x
    Unity C#编程优化——枚举

    我讨厌C#的枚举类型。我都会尽量避免它??悸窍旅婀赜谛行敲毒俚恼飧隼樱?/font>

    [mw_shl_code=csharp,true]public enum Planet {
        MERCURY,
        VENUS,
        EARTH,
        MARS,
        JUPITER,
        SATURN,
        URANUS,
        NEPTUNE,
        PLUTO // Pluto is a planet!!!
    }[/mw_shl_code]

    起初,这样的定义还算好,直到需要产生一个行星的质量。所以我们做这样的事情:

    [mw_shl_code=csharp,true]// Returns the mass of the planet in 10^24 kg
    public float GetMass(Planet planet) {
        switch(planet) {
            case Planet.MERCURY:
                return 0.330;
            case Planet.VENUS:
                return 4.87f;
            case Planet.EARTH:
                return 5.97f;
            ...
            case Planet.PLUTO:
                return 0.0146f;
        }
    }[/mw_shl_code]

    行星直径又如何? 另一个switch语句? 密度怎么样? 重力? 逃跑速度? 只要想想你将要维护的switch语句的数量。 你可以争辩说,你可以使用一个Dictionary,但仍然笨重。 每个数据的Dictionary都要映射?没门。

    有一个更好的方法,我会告诉你如何。 这可能已经是非Unity程序员的常识,但我想在我的博客中再次提出这个冗余的主题,对于那些可能不知道这一点的人来说,特别是初学者。 我也想保持简单。

    基本上,你可以使用类作为枚举。 为什么用类? 这确实表现的更好 您可以存储任意数量的任意数据。 您甚至可以存储例程或功能。 你可以做很多事情。 唯一的要求是它是不可变的,这意味着类一个实例的状态在整个程序期间都不能改变。以下是Planet枚举用类表示的一个版本:


       [mw_shl_code=csharp,true] public class Planet {
            // The different values
            public static readonly Planet MERCURY = new Planet(0, 0.330f, 4879, 5427, 3.7f);
            public static readonly Planet VENUS = new Planet(1, 4.87f, 12104, 5243, 8.9f);
            public static readonly Planet EARTH = new Planet(2, 5.97f, 12756, 5514, 9.8f);
            public static readonly Planet MARS = new Planet(3, 0.642f, 6792, 3933, 3.7f);
            public static readonly Planet JUPITER = new Planet(4, 1898.0f, 142984, 1326, 23.1f);
            public static readonly Planet SATURN = new Planet(5, 568.0f, 120536, 687, 9.0f);
            public static readonly Planet URANUS = new Planet(6, 86.8f, 51118, 1271, 8.7f);
            public static readonly Planet NEPTUNE = new Planet(7, 102.0f, 49528, 1638, 11.0f);
            public static readonly Planet PLUTO = new Planet(8, 0.0146f, 2370, 2095, 0.7f);
            // Use readonly to maintain immutability
            private readonly int id;
            private readonly float mass; // in 10^24 kg
            private readonly int diameter; // in km
            private readonly int density; // in kg/m^3
            private readonly float gravity; // in m/s^2
            // We use a private constructor because this should not be instantiated
            // anywhere else.
            private Planet(int id, float mass, int diameter, int density, float gravity) {
                this.id = id;
                this.mass = mass;
                this.diameter = diameter;
                this.density = density;
                this.gravity = gravity;
            }
            public int Id {
                get {
                    return id;
                }
            }
            public float Mass {
                get {
                    return mass;
                }
            }
            public int Diameter {
                get {
                    return diameter;
                }
            }
            public int Density {
                get {
                    return density;
                }
            }
            public float Gravity {
                get {
                    return gravity;
                }
            }
        }[/mw_shl_code]


    为了保持不变性,所有成员变量应该是只读的。 一旦他们被分配,他们将不能再被改变。 这很重要,因为作为枚举,它的内部值不应该改变。 然后将每个枚举值实现为该类的静态只读实例。

    这是怎么用的? 与正常枚举是一样的,如下使用:


    [mw_shl_code=csharp,true]// Use it like an enum
    ship.TargetPlanet = Planet.NEPTUNE;
    // Want to know the target planet's mass?
    float mass = ship.TargetPlanet.Mass;
    // Density?
    int density = ship.TargetPlanet.Density;[/mw_shl_code]


    我们已经消除了切换语句或字典来维护不同行星信息的需要。 想要一个新的行星状态? 只需添加一个新的成员变量并在实例化上指定它们。

    如何从其他数据类型转换? 喜欢说从int id转换为Planet实例? 这很容易 通常我为这些转换添加了一个公共和静态方法。 例如:


    [mw_shl_code=csharp,true]public class Planet {
        // The different values
        public static readonly Planet MERCURY = new Planet(0, 0.330f, 4879, 5427, 3.7f);
        public static readonly Planet VENUS = new Planet(1, 4.87f, 12104, 5243, 8.9f);
        public static readonly Planet EARTH = new Planet(2, 5.97f, 12756, 5514, 9.8f);
        public static readonly Planet MARS = new Planet(3, 0.642f, 6792, 3933, 3.7f);
        public static readonly Planet JUPITER = new Planet(4, 1898.0f, 142984, 1326, 23.1f);
        public static readonly Planet SATURN = new Planet(5, 568.0f, 120536, 687, 9.0f);
        public static readonly Planet URANUS = new Planet(6, 86.8f, 51118, 1271, 8.7f);
        public static readonly Planet NEPTUNE = new Planet(7, 102.0f, 49528, 1638, 11.0f);
        public static readonly Planet PLUTO = new Planet(8, 0.0146f, 2370, 2095, 0.7f);
        // This can be used to loop through all planets
        public static Planet[] ALL = new Planet[] {
            MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE, PLUTO
        };
        // Converts the specified id to a Planet instance
        public static Planet Convert(int id) {
            for(int i = 0; i < ALL.Length; ++i) {
                if(ALL.Id == id) {
                    return ALL;
                }
            }
            // return ALL[id] could also work here but what if a non sequential id is used?
            throw new Exception("Cannot convert {0} to a Planet.".FormatWith(id));
        }
        ...
    }
    // Usage
    Planet planet = Planet.Convert(someIntPlanet);[/mw_shl_code]

    想从字符串ID转换? 添加将保存此值的字符串成员变量。 而不是使用诸如ALL []的数组,您可以使用如下所示的Dictionary:
    [mw_shl_code=csharp,true]private static Dictionary<string, Planet> ALL = new Dictionary<string, Planet>() {
        { MERCURY.TextId, MERCURY },
        { VENUS.TextId, VENUS },
        { EARTH.TextId, EARTH },
        ...
        { PLUTO.TextId, PLUTO },
    };
    // Converts the specified string to a Planet instance
    public static Planet Convert(string id) {
        return ALL[id];
    }[/mw_shl_code]

    您可以支持您喜欢的任何类型的转换。
    还有更多的你可以做。 您现在可以添加功能。 你可以这样做:

    [mw_shl_code=csharp,true]Planet currentPlanet = Planet.VENUS;
    currentPlanet.ApplyGravity(ship);
    The coolest thing for me is you can specify different actions or behavior to the enum values. Something like this (It’s very contrived but you get the idea.):
    public static readonly Planet EARTH = new Planet(2, 5.97f, 12756, 5514, 9.8f, delegate(Ship ship) {
        // Actions on land of ship
        ship.AddFood(1000);
        ship.RetireCrew();
        ship.RecruitNewCrew();
    });
    public static readonly Planet MARS = new Planet(3, 0.642f, 6792, 3933, 3.7f, delegate(Ship ship) {
        // Actions on land of ship
        ship.DeductFood(50);
        ship.Research();
        ship.Mine();
    });[/mw_shl_code]

    通过简单地将你的枚举变成一个类,你已经将它升级到更有组织的东西,而且更加功能强大。 您也可以使用反射和继承等先进功能,但大多数情况下,您不需要。
    希望这可以帮助你。








    原文标题:Better C# Enums
    原文链接:https://coffeebraingames.wordpress.com/2017/10/08/better-c-enums/

    点评

    很有用,多谢了!  发表于 2018-10-30 09:13
    参与人数 1鲜花 +2 收起 理由
    xinansky + 2

    查看全部评分总评分 : 鲜花 +2

    本帖被以下淘专辑推荐:

    3偶尔光临
    254/300
    排名
    14227
    昨日变化

    0

    主题

    122

    帖子

    254

    积分

    Rank: 3Rank: 3Rank: 3

    UID
    155121
    好友
    0
    蛮牛币
    126
    威望
    0
    注册时间
    2016-7-4
    在线时间
    74 小时
    最后登录
    2017-12-16
    沙发
    2017-10-16 05:37:56 只看该作者
    ...那么,有什么意义?
    [发帖际遇]: 一个袋子砸在了 gcorpse 头上,gcorpse 赚了 1 蛮牛币. 幸运榜 / 衰神榜
    7日久生情
    4380/5000
    排名
    2320
    昨日变化

    5

    主题

    3110

    帖子

    4380

    积分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    209186
    好友
    5
    蛮牛币
    1131
    威望
    0
    注册时间
    2017-3-1
    在线时间
    653 小时
    最后登录
    2019-3-22
    板凳
    2017-10-16 09:16:52 只看该作者
    很实用,收藏了
    6蛮牛粉丝
    1102/1500
    排名
    3288
    昨日变化

    2

    主题

    214

    帖子

    1102

    积分

    Rank: 6Rank: 6Rank: 6

    UID
    55491
    好友
    1
    蛮牛币
    1717
    威望
    0
    注册时间
    2014-11-14
    在线时间
    418 小时
    最后登录
    2019-3-22
    地板
    2017-10-16 13:37:45 只看该作者
    我想说,这并不是优化,这只是因为枚举并不合适在这个例子中!这是设计上的缺陷导致的!不要把锅甩给枚举
    [发帖际遇]: z534605060 发帖时在路边捡到 2 蛮牛币,偷偷放进了口袋. 幸运榜 / 衰神榜
    7日久生情
    1707/5000
    排名
    2262
    昨日变化

    0

    主题

    638

    帖子

    1707

    积分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    182268
    好友
    2
    蛮牛币
    805
    威望
    0
    注册时间
    2016-11-9
    在线时间
    446 小时
    最后登录
    2019-3-10
    5#
    2017-10-16 14:05:16 只看该作者
    排名
    48126
    昨日变化

    0

    主题

    4

    帖子

    12

    积分

    Rank: 1

    UID
    249029
    好友
    0
    蛮牛币
    25
    威望
    0
    注册时间
    2017-10-16
    在线时间
    4 小时
    最后登录
    2018-4-26
    6#
    2017-10-16 17:07:16 只看该作者
    不但是复杂,而且逻辑也被强行耦合到了一起。
    这么做意义何在。。。

    你可能是想说明枚举对于你将使用的静态数据用起来没那么方便,
    所以做了一个静态类,貌似看起来方便了很多,

    枚举只能存一个数据,而你需要很多数据。
    当你想存很多数据的时候,你怪枚举没有用?
    这就是你的逻辑?
    8常驻蛮牛
    7574/10000
    排名
    251
    昨日变化

    0

    主题

    3902

    帖子

    7574

    积分

    Rank: 8Rank: 8

    UID
    3215
    好友
    0
    蛮牛币
    231
    威望
    0
    注册时间
    2013-9-4
    在线时间
    1676 小时
    最后登录
    2019-3-25
    7#
    2017-10-16 17:23:35 只看该作者
    好好好, 非常好
    6蛮牛粉丝
    1385/1500
    排名
    1338
    昨日变化

    7

    主题

    114

    帖子

    1385

    积分

    Rank: 6Rank: 6Rank: 6

    UID
    215462
    好友
    1
    蛮牛币
    3237
    威望
    0
    注册时间
    2017-3-30
    在线时间
    352 小时
    最后登录
    2019-3-25
    8#
    2017-10-17 13:56:13 只看该作者
    赞同楼上的几个同仁的看法,将枚举用在这个地方本来就是不对的.就像用方块去填补一个圆形的空洞,然后说不合适
    6蛮牛粉丝
    1385/1500
    排名
    1338
    昨日变化

    7

    主题

    114

    帖子

    1385

    积分

    Rank: 6Rank: 6Rank: 6

    UID
    215462
    好友
    1
    蛮牛币
    3237
    威望
    0
    注册时间
    2017-3-30
    在线时间
    352 小时
    最后登录
    2019-3-25
    9#
    2017-10-17 13:57:21 只看该作者
    刚刚忘记了,但是,改篇文章已经收藏了,感谢楼主
    [发帖际遇]: new_wind 发帖时在路边捡到 2 蛮牛币,偷偷放进了口袋. 幸运榜 / 衰神榜
    7日久生情
    1675/5000
    排名
    2252
    昨日变化

    0

    主题

    495

    帖子

    1675

    积分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    163777
    好友
    1
    蛮牛币
    526
    威望
    0
    注册时间
    2017-2-27
    在线时间
    556 小时
    最后登录
    2019-3-25
    10#
    2017-10-18 09:04:49 只看该作者
    我也不喜欢枚举
    6蛮牛粉丝
    1138/1500
    排名
    3865
    昨日变化

    0

    主题

    527

    帖子

    1138

    积分

    Rank: 6Rank: 6Rank: 6

    UID
    156480
    好友
    0
    蛮牛币
    1849
    威望
    0
    注册时间
    2016-7-12
    在线时间
    225 小时
    最后登录
    2018-3-16
    11#
    2017-10-18 09:06:03 只看该作者
    666666666666666666
    4四处流浪
    428/500
    排名
    5860
    昨日变化

    0

    主题

    46

    帖子

    428

    积分

    Rank: 4

    UID
    236479
    好友
    0
    蛮牛币
    204
    威望
    0
    注册时间
    2017-8-8
    在线时间
    146 小时
    最后登录
    2018-7-27
    12#
    2017-10-18 09:55:50 只看该作者
    外国文章可能表达上会比较主观点,也可以当作者提供了一种减少判断语句的思路吧
    4四处流浪
    352/500
    排名
    7538
    昨日变化

    0

    主题

    105

    帖子

    352

    积分

    Rank: 4

    UID
    236962
    好友
    1
    蛮牛币
    591
    威望
    0
    注册时间
    2017-8-10
    在线时间
    81 小时
    最后登录
    2018-11-22
    QQ
    13#
    2017-10-18 10:23:33 只看该作者
    初级理解起来还是挺困难的
    7日久生情
    2741/5000
    排名
    665
    昨日变化

    30

    主题

    578

    帖子

    2741

    积分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    124569
    好友
    25
    蛮牛币
    7415
    威望
    0
    注册时间
    2015-10-4
    在线时间
    807 小时
    最后登录
    2019-3-14
    14#
    2017-10-19 09:39:52 只看该作者
    66666666666666666666666
    5熟悉之中
    548/1000
    排名
    5083
    昨日变化

    0

    主题

    130

    帖子

    548

    积分

    Rank: 5Rank: 5

    UID
    38463
    好友
    0
    蛮牛币
    380
    威望
    0
    注册时间
    2014-8-6
    在线时间
    134 小时
    最后登录
    2018-6-11
    15#
    2017-10-19 17:28:57 只看该作者
    我觉得吧!复杂的事情还是简单化好点,也许对于楼主来说这种设计思想方便了这个项目的扩展性能,但是枚举的存在就是为了描述说明,我想你的框架应该可以扩展成工厂模式,抽离出唯一实例化接口,通过不同的枚举实例化不同的对象;仁者见仁,智者见智啦
    [发帖际遇]: Gray 在论坛发帖时没有注意,被小偷偷去了 1 蛮牛币. 幸运榜 / 衰神榜
    您需要登录后才可以回帖 登录 | 注册帐号

    本版积分规则

  • 新疆花开天山南北 笑迎八方来客 2019-03-25
  • 机器人占领就业市场后:人类还能从事这些工作 2019-03-04
  • 以网络文化建设推进文化惠民 2019-03-03
  • 贸易战,只能是双输。我们是众志成城,美国却不一定。 2019-02-26
  • 辣评2016年9月最HOT 轿车获奖榜单 2019-02-22
  • 交通运输部路网中心:端午假期高速通行不免费 2019-02-18
  • 《陕西省县域经济社会发展监测考评办法》解读 2019-02-18
  • 西部网(陕西新闻网)www.cnwest.com 2019-02-13
  • 短途一日游 游客量猛增 小长假新疆接待游客353.6万人次 2019-02-13
  • 南昌重拳整治酒驾毒驾 2019-02-08
  • 女性之声——全国妇联 2019-02-08
  • 信息网络传播视听节目许可证 2019-02-03
  • 打开书籍,了解文物背后的中国温度 2019-02-03
  • 中央环保督察组:石家庄市无极县“敷衍整改” 2019-02-02
  • China Focus Dragon Boat Festival celebrated across China - Culture News - CQNEWS 2019-02-02