为属性分配随机枚举值

时间:2015-06-09 16:30:18

标签: c# enums

你好,我正在努力完成一项任务。我需要为属性分配一个随机BEGIN TRANSACTION GO -- necessary to define the fake sp1 for this script create procedure sp1 @id int, @type int, @orderno int as SELECT @id, @type, @orderno ; GO declare @temp_tbl TABLE (id int, [type] int, orderno int); insert into @temp_tbl EXEC sp1 1,2,3 SELECT * FROM @temp_tbl; -- this works, no EXEC() needed! DECLARE @select VARCHAR(MAX); SET @select = 'SELECT * FROM @temp_tbl;' EXEC (@select); -- FAILS: @temp_tbl is a VARIABLE and NOT IN SCOPE!; SELECT * INTO #temp_tbl FROM @temp_tbl ; -- copy local TABLE VAR to TEMP Table (stored in temp db, private) SET @select = 'SELECT * FROM #temp_tbl;' -- note @ changed to # EXEC (@select); -- This also works, because temp table are in scope ROLLBACK -- cleanup this test 。我的代码就是这个。

enum

和其他看起来像这样的课程

public enum PegColour
{
    Red, Green, Blue, Yellow, Black, White
}

我的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() { } } 方法应该在每次调用时随机将其中一种GeneratePegs()颜色分配给其中一个属性(enumColour1等)以使其复杂化我需要随机函数来忽略Colour2Black

4 个答案:

答案 0 :(得分:5)

枚举只是整数,因此可以将整数强制转换为枚举。我会这样做:

Random rnd = new Random();

public enum PegColour
{
    Red, Green, Blue, Yellow, Black, White
}

private PegColour GetRandomColoredPeg()
{
    PegColour color = (PegColour)rnd.Next(0, Enum.GetNames(typeof(PegColour)).Length - 2);
    return color;
}

黑色和白色永远不会被选中,因为它只从前4种颜色中随机挑选。只要你在黑白钉之前添加钉子,这个代码应该每次都有效,即使你在枚举中添加或删除钉子也是如此。因此,如果您想添加新颜色,只需将PegColour更改为以下内容:

public enum PegColour
{
    Red, Green, Blue, Yellow, Purple, Orange, Pink, Black, White
}

你不需要改变任何其他东西!

因此,您的GeneratePegs()方法应该如下所示:

public void GeneratePegs()
{
    Colour1 = GetRandomColoredPeg();
    Colour2 = GetRandomColoredPeg();
    Colour3 = GetRandomColoredPeg();
    Colour4 = GetRandomColoredPeg();
}

答案 1 :(得分:4)

一个简单的解决方案可能是创建一个包含所有符合条件的值的数组:

PegColour[] eligibleValues = new[] { PegColour.Red, PegColour.Blue, PegColour.Green, PegColour.Yellow };

然后,您可以使用Random的实例随机选择该数组中的索引:

var myRandomColour = eligibleValues[myRandom.Next(eligibleValues.Length)];

这样做的一个优点是您不必为enum常量指定任何特定的数值,以便随机选择起作用。这样,如果需要,您仍然可以自由地定义和使用数值以用于其他目的。

现在,在PegColour经常使用新元素进行扩展的情况下,此可能仍然有点不方便。在这种情况下,您可以在Enum.GetValues method初始化后检索当前定义的常量的完整列表(请注意,此代码段假定已导入System.Linq namespace以允许从{{3}访问扩展方法}}):

PegColour[] eligibleValues = Enum.GetValues(typeof(PegColour)).Cast<PegColour>().ToArray();

显然,这还不能满足排除某些颜色的要求。因此,您可以直接在数组创建表达式中对此限制进行硬编码:

PegColour[] eligibleValues = Enum.GetValues(typeof(PegColour)).Cast<PegColour>().Where(pc => (pc != PegColour.Black) && (pc != PegColour.White)).ToArray();

...或存储要在某些System.Linq.Enumerable中排除的颜色,以使事物更具可扩展性:

PegColour[] eligibleValues = Enum.GetValues(typeof(PegColour)).Cast<PegColour>().Where(pc => !myExcludedColours.Contains(pc)).ToArray();

请注意,您始终可以放置此代码以便仅初始化eligibleValues一次,而不是每次随机检索值。这样可以避免不必要的set,以及不必要地重新生成数组。

答案 2 :(得分:2)

我建议你创建一个列表:

var pegs = new List<Peg> { Peg.Red, Peg.Green, Peg.Blue, Peg.Yellow };

然后使用the accepted answer to this questio n,随机排序。最后,将值分配给pegs:

Colour1 = pages[0];
Colour2 = pages[1];
Colour3 = pages[2];
Colour4 = pages[3];

答案 3 :(得分:0)

我为Random对象创建了一个非常通用的扩展方法,该方法生成Enum类型的随机值。这适用于各种混乱的枚举,包括具有可怕编号方案的枚举。这是通过使用Enum.GetValues获取Enum的所有可能值来实现的。然后随机选择随机可能的值。

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);
}   

此扩展方法的调用如下:

var randomColor = rand.GetRandomEnum<ColorType>(new List<Colors> 
{ 
    Colors.White, 
    Colors.Black
});

A demo