• 天津宣讲十九大:津沽大地舞春风,小康路上添豪情 2019-05-21
  • 酱香酒为什么要在端午时节制曲微生物 酒曲 2019-05-20
  • 回复@艾鸣1:你看强坛除了小寻子这种跟你一样老蚕的人之外,有人会有人敢支持你么? 2019-05-15
  • 中国经济稳中向好的发展态势没有变 2019-05-14
  • 私扫码付不加控制党政和人行国有银行国有企业自动退出历史舞台 2019-05-11
  • 你真没一点脑子,文字是哪个人的,你到说说啊 2019-05-04
  • 黎明华丽转身成监制 他给四川金丝猴拍了部动画片 2019-05-04
  • 候选案例:爱在华住滇西北宿改工程 2019-05-02
  • 山西寿阳:竹马戏演员的台前幕后 2019-04-26
  • 96次航拍峨眉 换个角度看巴蜀名山 中国国家地理网 2019-04-23
  • 俄罗斯电影《最后一球》定档落魄球星遇上菜鸟球队 2019-04-21
  • 【理上网来·辉煌十九大】缅甸资深媒体人高度评价习近平十九大报告:立意高远 内涵丰富 2019-04-21
  • 特朗普和金正恩先后抵达嘉佩乐酒店 会晤即将开始 2019-04-17
  • 中国侨联直属机关党委举办党务干部培训班 2019-04-17
  • 上海合作组织青岛峰会举行 2019-04-07
  • 我要福建体彩31走势图: DevTips Unity C#编程优化——枚举

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

    福建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
    排名
    14227
    昨日变化

    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日久生情
    4381/5000
    排名
    2320
    昨日变化

    5

    主题

    3109

    帖子

    4381

    积分

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

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

    2

    主题

    214

    帖子

    1102

    积分

    Rank: 6Rank: 6Rank: 6

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

    0

    主题

    642

    帖子

    1712

    积分

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

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

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

    0

    主题

    3904

    帖子

    7596

    积分

    Rank: 8Rank: 8

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

    7

    主题

    115

    帖子

    1397

    积分

    Rank: 6Rank: 6Rank: 6

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

    7

    主题

    115

    帖子

    1397

    积分

    Rank: 6Rank: 6Rank: 6

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

    0

    主题

    561

    帖子

    1777

    积分

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

    UID
    163777
    好友
    1
    蛮牛币
    525
    威望
    0
    注册时间
    2017-2-27
    在线时间
    592 小时
    最后登录
    2019-4-3
    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
    蛮牛币
    7419
    威望
    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 只看该作者
    我觉得吧!复杂的事情还是简单化好点,也许对于楼主来说这种设计思想方便了这个项目的扩展性能,但是枚举的存在就是为了描述说明,我想你的框架应该可以扩展成工厂模式,抽离出唯一实例化接口,通过不同的枚举实例化不同的对象;仁者见仁,智者见智啦
    您需要登录后才可以回帖 登录 | 注册帐号

    本版积分规则

  • 天津宣讲十九大:津沽大地舞春风,小康路上添豪情 2019-05-21
  • 酱香酒为什么要在端午时节制曲微生物 酒曲 2019-05-20
  • 回复@艾鸣1:你看强坛除了小寻子这种跟你一样老蚕的人之外,有人会有人敢支持你么? 2019-05-15
  • 中国经济稳中向好的发展态势没有变 2019-05-14
  • 私扫码付不加控制党政和人行国有银行国有企业自动退出历史舞台 2019-05-11
  • 你真没一点脑子,文字是哪个人的,你到说说啊 2019-05-04
  • 黎明华丽转身成监制 他给四川金丝猴拍了部动画片 2019-05-04
  • 候选案例:爱在华住滇西北宿改工程 2019-05-02
  • 山西寿阳:竹马戏演员的台前幕后 2019-04-26
  • 96次航拍峨眉 换个角度看巴蜀名山 中国国家地理网 2019-04-23
  • 俄罗斯电影《最后一球》定档落魄球星遇上菜鸟球队 2019-04-21
  • 【理上网来·辉煌十九大】缅甸资深媒体人高度评价习近平十九大报告:立意高远 内涵丰富 2019-04-21
  • 特朗普和金正恩先后抵达嘉佩乐酒店 会晤即将开始 2019-04-17
  • 中国侨联直属机关党委举办党务干部培训班 2019-04-17
  • 上海合作组织青岛峰会举行 2019-04-07