新宝娱乐城赌球: DevTips Unity C#编程优化——枚举

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

新宝娱乐城博彩打不开 www.sl6cl.com.cn 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
排名
14228
昨日变化
1

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

5

主题

3110

帖子

4388

积分

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

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

2

主题

214

帖子

1103

积分

Rank: 6Rank: 6Rank: 6

UID
55491
好友
1
蛮牛币
1715
威望
0
注册时间
2014-11-14
在线时间
421 小时
最后登录
2019-4-6
地板
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 只看该作者
排名
48129
昨日变化

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

0

主题

3915

帖子

7613

积分

Rank: 8Rank: 8

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

7

主题

120

帖子

1411

积分

Rank: 6Rank: 6Rank: 6

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

7

主题

120

帖子

1411

积分

Rank: 6Rank: 6Rank: 6

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

0

主题

634

帖子

1865

积分

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

UID
163777
好友
1
蛮牛币
532
威望
0
注册时间
2017-2-27
在线时间
607 小时
最后登录
2019-4-22
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
排名
7538
昨日变化

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

30

主题

578

帖子

2742

积分

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

UID
124569
好友
25
蛮牛币
7431
威望
0
注册时间
2015-10-4
在线时间
809 小时
最后登录
2019-4-16
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-04-22
  • 杰森·斯坦森:《巨齿鲨》水下拍摄难度大 2019-04-22
  • 一张门票免签两国!白俄罗斯世界杯期间对球迷免签 2019-04-21
  • 近九成券商股逆市上涨 防御+反弹攻守兼备 2019-04-21
  • 女友提分手小伙以死相逼 警察破门救助被划伤 2019-04-20
  • 流动人口的户籍迁移意愿及其影响因素分析 2019-04-19
  • Angelababy上海街头拍大片 都市简约风优雅显气质 2019-04-19
  • 【群友杂谈】——农村、农民、农地 2019-04-18
  • 年轻妈妈留下遗书 携刚出生10天的婴儿在河中溺亡 2019-04-17
  • 中国三大球备战里约奥运 2019-04-16
  • 达州消防成功处置一起天然气泄漏事故 2019-04-15
  • 房产--山西频道--人民网 2019-04-15
  • 人民性是马克思主义最鲜明的品格 2019-04-14
  • 【拜年啦!】强坛嘉宾送祝福,看哪位大咖的心愿戳中你的心! 2019-04-13
  • 【互动话题】一句话形容过完年的你 2019-04-13
  • 319| 473| 888| 784| 565| 43| 161| 495| 251| 128|