• 外国人就医计划示范医院授牌 天津医院泰达医院获认定 2019-07-21
  • 文体 —频道 春城壹网 七彩云南 一网天下 2019-07-18
  • 【理上网来喜迎十九大】苏格:习近平总书记外交思想领航中国特色大国外交 2019-07-18
  • 8种家居环境很败“性” 2019-06-28
  • 2018年全军院校招生计划下达:计划招收学员3.05万名 2019-06-15
  • 晋城市举办干部素质提升工程第十八期专题讲座 2019-06-15
  • 抖音广告出现对英烈邱少云不敬内容 今日头条致歉 2019-06-13
  • 超半数巴西民众对世界杯不感兴趣--旅游频道 2019-06-12
  • 外交部举行中外媒体吹风会:王毅介绍上合组织青岛峰会情况 2019-06-12
  • 2018网络中国节·端午 2019-06-04
  • 韩媒:韩美商定暂停原定8月“乙支自由卫士”联演 2019-06-03
  • 重庆市公安局交通管理局互联网交通安全服务管理平台 2019-06-03
  • 俄侦察船穿越英吉利海峡 英国急派军舰战机监视 2019-05-28
  • 网购陷阱多 女子花3000元买5套化妆品只有2套是真的 2019-05-28
  • 环保约谈濂溪区主要负责同志 谢一平要求立行立改真抓真改 2019-05-25
  • 福建体彩31选7今日开奖: DevTips Unity C#编程优化——枚举

    152
    回复
    22146
    查看
    打印 上一主题 下一主题
      [ 复制链接 ]
    排名
    9776
    昨日变化

    福建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>

    [C#] 纯文本查看 复制代码
    public enum Planet {
        MERCURY,
        VENUS,
        EARTH,
        MARS,
        JUPITER,
        SATURN,
        URANUS,
        NEPTUNE,
        PLUTO // Pluto is a planet!!!
    }


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

    [C#] 纯文本查看 复制代码
    // 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;
        }
    }


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

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

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


       
    [C#] 纯文本查看 复制代码
     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;
                }
            }
        }


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

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


    [C#] 纯文本查看 复制代码
    // 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;



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

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


    [C#] 纯文本查看 复制代码
    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);


    想从字符串ID转换? 添加将保存此值的字符串成员变量。 而不是使用诸如ALL []的数组,您可以使用如下所示的Dictionary:
    [C#] 纯文本查看 复制代码
    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];
    }


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

    [C#] 纯文本查看 复制代码
    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();
    });


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








    原文标题: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
    排名
    14229
    昨日变化

    0

    主题

    121

    帖子

    254

    积分

    Rank: 3Rank: 3Rank: 3

    UID
    155121
    好友
    0
    蛮牛币
    126
    威望
    0
    注册时间
    2016-7-4
    在线时间
    74 小时
    最后登录
    2017-12-16
    沙发
    2017-10-16 05:37:56 只看该作者
    ...那么,有什么意义?
    7日久生情
    4395/5000
    排名
    2320
    昨日变化

    5

    主题

    3108

    帖子

    4395

    积分

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

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

    2

    主题

    214

    帖子

    1108

    积分

    Rank: 6Rank: 6Rank: 6

    UID
    55491
    好友
    1
    蛮牛币
    1696
    威望
    0
    注册时间
    2014-11-14
    在线时间
    424 小时
    最后登录
    2019-6-24
    地板
    2017-10-16 13:37:45 只看该作者
    我想说,这并不是优化,这只是因为枚举并不合适在这个例子中!这是设计上的缺陷导致的!不要把锅甩给枚举
    7日久生情
    1714/5000
    排名
    2263
    昨日变化

    0

    主题

    643

    帖子

    1714

    积分

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

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

    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常驻蛮牛
    7634/10000
    排名
    250
    昨日变化

    0

    主题

    3929

    帖子

    7634

    积分

    Rank: 8Rank: 8

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

    8

    主题

    138

    帖子

    1467

    积分

    Rank: 6Rank: 6Rank: 6

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

    8

    主题

    138

    帖子

    1467

    积分

    Rank: 6Rank: 6Rank: 6

    UID
    215462
    好友
    1
    蛮牛币
    3587
    威望
    0
    注册时间
    2017-3-30
    在线时间
    410 小时
    最后登录
    2019-6-25
    9#
    2017-10-17 13:57:21 只看该作者
    刚刚忘记了,但是,改篇文章已经收藏了,感谢楼主
    7日久生情
    2280/5000
    排名
    2252
    昨日变化

    0

    主题

    945

    帖子

    2280

    积分

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

    UID
    163777
    好友
    2
    蛮牛币
    811
    威望
    0
    注册时间
    2017-2-27
    在线时间
    711 小时
    最后登录
    2019-6-28
    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
    排名
    5861
    昨日变化

    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四处流浪
    355/500
    排名
    7540
    昨日变化

    0

    主题

    105

    帖子

    355

    积分

    Rank: 4

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

    30

    主题

    577

    帖子

    2751

    积分

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

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

    0

    主题

    129

    帖子

    548

    积分

    Rank: 5Rank: 5

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

    本版积分规则

  • 外国人就医计划示范医院授牌 天津医院泰达医院获认定 2019-07-21
  • 文体 —频道 春城壹网 七彩云南 一网天下 2019-07-18
  • 【理上网来喜迎十九大】苏格:习近平总书记外交思想领航中国特色大国外交 2019-07-18
  • 8种家居环境很败“性” 2019-06-28
  • 2018年全军院校招生计划下达:计划招收学员3.05万名 2019-06-15
  • 晋城市举办干部素质提升工程第十八期专题讲座 2019-06-15
  • 抖音广告出现对英烈邱少云不敬内容 今日头条致歉 2019-06-13
  • 超半数巴西民众对世界杯不感兴趣--旅游频道 2019-06-12
  • 外交部举行中外媒体吹风会:王毅介绍上合组织青岛峰会情况 2019-06-12
  • 2018网络中国节·端午 2019-06-04
  • 韩媒:韩美商定暂停原定8月“乙支自由卫士”联演 2019-06-03
  • 重庆市公安局交通管理局互联网交通安全服务管理平台 2019-06-03
  • 俄侦察船穿越英吉利海峡 英国急派军舰战机监视 2019-05-28
  • 网购陷阱多 女子花3000元买5套化妆品只有2套是真的 2019-05-28
  • 环保约谈濂溪区主要负责同志 谢一平要求立行立改真抓真改 2019-05-25
  • 竞彩足球胜分差 华东15选5预测分析 易算北京赛车pk10北京pk拾 泳坛夺金18053047期 福彩6十1生肖开奖结果 福彩幸运农场 极速飞艇是正规的吗 麻将连连看 湖北30选5开奖公告 一肖中特连准八期 绝版解透码图 排列五历史开奖结果2019 中国体彩p3预测胆码 好运快35分开奖结果 2019大乐透走势图