Выберыце выпадковы статычную зменную з статычнага класа

У мяне ёсць спіс статычных зменных ў статычным класе.

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);
1
Для прыкладу гэта трывіяльна, таму я мяркую, што ёсць больш да яго. Вы ведаеце загадзя тып класа, як у вашым прыкладзе?
дададзена аўтар Matthew Watson, крыніца
@RameshDurai Гэта не перашкаджае вам капіюючы усе статычныя зменныя ў свой уласны масіў.
дададзена аўтар Rotem, крыніца
чаму б не выкарыстоўваць пералік?!
дададзена аўтар makc, крыніца
@MatthewWatson: Так. Я ведаю загадзя тып класа ..
дададзена аўтар Ramesh Durai, крыніца
@makc: Класс Лік гэта з DLL трэцяга боку
дададзена аўтар Ramesh Durai, крыніца

6 адказы

Выкарыстанне адлюстравання:

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

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

<�Моцны> Лепшае рашэнне без адлюстравання:

Стварыць масіў цэлых лікаў Лікі як статычнае ўласцівасць і ініцыялізаваць яго значэння ў класе Лікі :

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

Тады пры атрыманні выпадковай велічыні:

int randomVariable = Numbers[rnd.Next(Numbers.Length)];
5
дададзена
+1, але не забывайце, што вы сапраўды </я> хочаце, каб ваш Random , каб быць у якасці члена або статычнай зменнай, а не лакальнай зменнай, як гэта.
дададзена аўтар Rawling, крыніца
  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

Але ўвогуле-то вельмі дзіўнае выкарыстанне статычных палёў, я б перагледзець праект, калі ўсё ў парадку з гэтым.

4
дададзена
выкарыстоўваючы Guid.NewGuid() здаецца трохі цяжкім, чаму б не выкарыстоўваць Random ?
дададзена аўтар Dai, крыніца
з дапамогай адлюстравання цяжэй, чым пры выкарыстанні Guid я думаю, так што гэта было карацей выкарыстоўваць Guid :)
дададзена аўтар Giedrius, крыніца
Guids ня правільна выпадковая і не павінна выкарыстоўвацца для гэтай мэты. stackoverflow.com/questions/467271/…
дададзена аўтар Matthew Watson, крыніца

Вы можаце стварыць масіў Міжнар, генераваць выпадковы лік паміж верхнім і ніжнім індэксам масіва і індэксам масіва доступу з ім.

У адваротным выпадку, для вашага падыходу да працы, неабходна выкарыстоўваць адлюстраванне, якое мае зніжэнне прадукцыйнасці і не вельмі элегантныя .. Напрыклад, атрымаць усе PropertyInfos ў класе, ствараць і масіў з імі, атрымаць і выпадковы індэкс і выклікаць значэнне PropertyInfo ,

3
дададзена
Я згодны з гэтым ....
дададзена аўтар Arun, крыніца

Вы можаце зрабіць гэта з дапамогай адлюстравання на класе. Звярніце ўвагу, што калі вы не хочаце, каб пералічыць усе канстантнасцю Інтс, вам трэба будзе мець маркеры на іх, якія пералічыць. Гэта будзе зроблена з дапамогай карыстацкіх Атрыбуты ,

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 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();
    }
  }
}
2
дададзена
+1 Для Фільтраванне і прыстасаваныя атрыбуты .
дададзена аўтар Ramesh Durai, крыніца

Так як вы ведаеце тып, вам не трэба адлюстраванне - вось так проста, як гэта павінна быць у парадку:

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();
1
дададзена
@RameshDurai На жаль, я проста не заўважыў, які быў адпраўлены раней усіх. Ахмед быў першым, так што гэта адзін выбар. :)
дададзена аўтар Matthew Watson, крыніца
@RameshDurai Калі гэта, безумоўна, дакладна, то адказ ад nvoigt здаецца, што гэта можа быць правільным, за выключэннем таго, што ён выкарыстоўвае канстантнасцю , а не толькі для чытання
дададзена аўтар Matthew Watson, крыніца
Такім чынам, вы ўпэўненыя, што, так як вы карыстаецеся 3-ці тып партыі, то трэцяя бок не ў нейкі момант у будучыні дадаць грамадскае ўласцівасць толькі для чытання, што вы не </я> хачу ўключыць у выпадковай нумары? Таму што, калі вы выкарыстоўваеце адлюстраванне, што можа здарыцца.
дададзена аўтар Matthew Watson, крыніца
@RameshDurai Вы не азначае «цяжка» - вы маеце на ўвазе «цяжка і адымае шмат часу». ;)
дададзена аўтар Matthew Watson, крыніца
Гэта рашэнне здаецца добра. Але праблема ў тым, у мяне ёсць каля 100 зменных у класе Лікі . Гэта будзе цяжка пісаць выпадкі пераключэння.
дададзена аўтар Ramesh Durai, крыніца
Так! Вы правільна :)
дададзена аўтар Ramesh Durai, крыніца
Не!! Калі дадаць новую зменную, якая не будзе праблемай для мяне.
дададзена аўтар Ramesh Durai, крыніца
Проста ведаць. Якая розніца паміж адказамі Ahmed KRAIEM і nvoigt . Паколькі абодва яны выкарыстоўваюць Random .
дададзена аўтар Ramesh Durai, крыніца

Гэта можа быць дасягнута лягчэй, калі вы выкарыстоўваеце 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));
0
дададзена