我在静态类中有一个静态变量列表。
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);
答案 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));