Assigning a random enum value a property
大家好,我有一个任务要做。我需要将一个随机的
1 2 3 4 | public enum PegColour { Red, Green, Blue, Yellow, Black, White } |
以及其他类似的班级
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class PegContainer { /// <summary> /// Dfines the colour of the first peg /// </summary> public Peg Colour1 { get; set; } /// <summary> /// Dfines the colour of the secod peg /// </summary> public Peg Colour2 { get; set; } /// <summary> /// Dfines the colour of the third peg /// </summary> public Peg Colour3 { get; set; } /// <summary> /// Dfines the colour of the forth peg /// </summary> public Peg Colour4 { get; set; } public void GeneratePegs() { } } |
我的
枚举只是整数,因此整数可以强制转换为枚举。我会这样做:
1 2 3 4 5 6 7 8 9 10 11 12 |
黑白将永远不会被选中,因为它只从前4种颜色中随机选取。只要在黑白挂钩之前添加挂钩,即使在枚举中添加或删除挂钩,此代码也应该每次都有效。所以,如果你想增加新的颜色,你只需要把
1 2 3 4 | public enum PegColour { Red, Green, Blue, Yellow, Purple, Orange, Pink, Black, White } |
你不需要改变任何其他东西!
所以你的
1 2 3 4 5 6 7 | public void GeneratePegs() { Colour1 = GetRandomColoredPeg(); Colour2 = GetRandomColoredPeg(); Colour3 = GetRandomColoredPeg(); Colour4 = GetRandomColoredPeg(); } |
一个简单的解决方案是创建一个包含所有符合条件的值的数组:
1 | PegColour[] eligibleValues = new[] { PegColour.Red, PegColour.Blue, PegColour.Green, PegColour.Yellow }; |
然后,您可以使用EDOCX1的一个实例(0)随机选择该数组中的一个索引:
1 | var myRandomColour = eligibleValues[myRandom.Next(eligibleValues.Length)]; |
这样做的一个好处是,您不必为
现在,如果
1 |
显然,这还不能满足排除某些颜色的要求。因此,可以在数组创建表达式中直接硬编码此限制:
1 | PegColour[] eligibleValues = Enum.GetValues(typeof(PegColour)).Cast<PegColour>().Where(pc => (pc != PegColour.Black) && (pc != PegColour.White)).ToArray(); |
…或者将要排除的颜色存储在一些集合中,以使事物更具可扩展性:
1 | PegColour[] eligibleValues = Enum.GetValues(typeof(PegColour)).Cast<PegColour>().Where(pc => !myExcludedColours.Contains(pc)).ToArray(); |
请注意,始终可以放置此代码,以便只初始化一次
我建议您创建一个列表:
1 |
然后使用这个问题的公认答案,随机排序。最后,将值赋给PEG:
1 2 3 4 | Colour1 = pages[0]; Colour2 = pages[1]; Colour3 = pages[2]; Colour4 = pages[3]; |
我为生成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public static TEnum GetRandomEnum<TEnum>(this Random rand, IEnumerable<TEnum> excludedValues) { var type = typeof(TEnum); if (!type.IsEnum) throw new ArgumentException("Not an enum type"); var values = Enum.GetValues(type).Cast<TEnum>(); if (excludedValues != null && excludedValues.Any()) values = values.Except(excludedValues); //if you call this a lot, you could consider saving this collection in memory // and separate the logic to avoid having to re-generate the collection //create a random index for each possible Enum value //will never be out of bounds because it NextDouble returns a value //between 0 (inclusive) and 1 (exclusive) or [0, 1) int randomIndex = (int) (rand.NextDouble() * values.Count()); return values.ElementAt(randomIndex); } |
此扩展方法的调用方式如下:
1 2 3 4 5 |
演示。