从静态类中选择一个随机静态变量

时间:2013-06-05 08:01:03

标签: c# .net static

我在静态类中有一个静态变量列表。

namespace Test
{
  public static class Numbers
  {
    public static readonly int One = 1;
    public static readonly int Five = 5;
    public static readonly int Ten = 10;
    public static readonly int Eleven = 11;
    public static readonly int Fifteen= 15;
  }
}

我想在课堂上随机选择一个变量。我怎样才能做到这一点?

int randomVariable = SomeFunction(Numbers);

6 个答案:

答案 0 :(得分:5)

使用反射:

FieldInfo[] fields= typeof(Numbers).GetFields(
   BindingFlags.Public | BindingFlags.Static);

var rnd = new Random();
int randomVariable = (int) fields[rnd.Next(fields.Length)].GetValue(null);

没有反思的更好解决方案:

创建一个整数数组Numbers作为静态属性,并将其初始化为类Numbers中的值:

Numbers = fields.Select(f => (int)f.GetValue()).ToArray(); //int[]

然后获得随机值:

int randomVariable = Numbers[rnd.Next(Numbers.Length)];

答案 1 :(得分:4)

  var fields = typeof(Numbers).GetFields(BindingFlags.Static | BindingFlags.Public);
  var value = fields
         .OrderBy(x => Guid.NewGuid()) // order by random
         .First() // take first field
         .GetValue(null); // get it's value

但总的来说静态字段的使用非常奇怪,我会审查设计,如果一切都好的话。

答案 2 :(得分:3)

你可以创建一个int数组,在上下数组索引之间生成一个随机数,并用它来访问数组索引。

否则,对于你的工作方法,必须使用反射,这会产生性能损失并且不是很优雅。例如,获取类中的所有PropertyInfos,使用它们创建和数组,获取和随机索引并调用PropertyInfo值。

答案 3 :(得分:2)

您可以在课堂上使用reflection来完成此操作。请注意,如果您不想枚举所有const int,则需要在其上包含要枚举的标记。这将使用自定义Attributes完成。

namespace ConsoleApplication4
{
  using System;
  using System.Collections.Generic;
  using System.Linq;

  public class Holder
  {
    public const int Number1 = 7;

    public const int Number2 = 17;

    public const int Number3 = 42;

    public static IEnumerable<int> AllNumbers()
    {
      return
        typeof(Holder).GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)
                      .Where(p => p.FieldType == typeof(int))
                      .Select(p => (int)p.GetValue(null));
    }

    public static int RandomNumber(Random r)
    {
      var possibleNumbers = AllNumbers().ToList();

      var draw = r.Next(possibleNumbers.Count);

      return possibleNumbers[draw];
    }
  }

  public class Program
  {
    public static void Main()
    {
      var r = new Random();

      for (int i = 0; i < 10; i++)
      {
        Console.WriteLine(Holder.RandomNumber(r));
      }

      Console.WriteLine("Done");
      Console.ReadLine();
    }
  }
}

答案 4 :(得分:1)

既然您知道类型,那么您就不需要反射 - 所以这样简单就可以了:

public sealed class NumbersRandomizer
{
    readonly Random rng = new Random();

    public int RandomValue()
    {
        switch (rng.Next(5))
        {
            case 0: return Numbers.One;
            case 1: return Numbers.Five;
            case 2: return Numbers.Ten;
            case 3: return Numbers.Eleven;
            case 4: return Numbers.Fifteen;
        }
    }
}

您可以这样使用:

var randomizer = new NumbersRandomizer();
int value = randomizer.RandomValue();

答案 5 :(得分:0)

如果您使用Enum,则可以更轻松地实现这一目标。

public enum Numbers {
    One = 1,
    Five = 5,
    Ten = 10,
    Eleven = 11
    Fifteen = 15
}

然后随机选择枚举。

var numbers = Enum.GetValues(typeof(Numbers));

Number randomNumber = (Number)numbers.GetValue(new Random().Next(numbers.Length));