#c# #wpf
#c# #wpf
Вопрос:
У меня есть приложение WPF, которое имеет случайные шансы возникновения случайных событий. У меня есть оператор switch, подобный so, который переключает случайное число:
(property)
static Random RandomObject { get; set; } = new Random();
...
RandomObject = new Random();
switch (RandomObject.Next())
{
case 1 when RandomObject.Next(1, 3) == 2:
// a
case 1 when RandomObject.Next(1, 13) == 2:
// b
break;
}
По какой-то причине в режиме отладки весь переключатель пропускается полностью. Может кто-нибудь сказать мне, что я делаю не так или как я мог бы сделать так, чтобы это действительно сработало?
РЕДАКТИРОВАТЬ: Хорошо, может кто-нибудь сказать мне, как это исправить, потому что я помню, что придумал что-то похожее, что делает то, что я хочу сделать, и это сработало, но проблема в том, что мой жесткий диск разбился, поэтому я потерял все свои данные
Возможно ли это?
switch(RandomObject)
{
case 1 when RandomObject.Next(1,3) == 2:
//do stuff
break;
}
Комментарии:
1. Так это работает в режиме выпуска?
2.
Random.Next()
будет возвращать случайное целое число от 0 до 2147483647. Затем вы ожидаете, что это значение будет равно 1, а затем ожидаете, что одно из внутренних случайных условий также будет истинным, чтобы выполнитьbreak
инструкцию. Так что дело не в том, что это не работает, просто это крайне маловероятно.3. Не могли бы вы, пожалуйста, объяснить, что, по вашему мнению, делает ваш код? Это поможет нам помочь вам.
4. @JohnG: Это называется «сопоставление с шаблоном». Смотрите здесь .
5. @Andy —
RandomObject.Next(1,5)
дает 1 шанс из 4, что число будет равно 1.
Ответ №1:
Я буду запускать тесты, чтобы попытаться показать вам, что происходит не так. Давайте возьмем этот код, который похож на ваш собственный:
int acount = 0, bcount = 0;
var r = new Random();
for(var i = 0; i < 1_000_000_000; i) // 1 billion iterations
{
switch (r.Next())
{
case 1 when r.Next(1, 3) == 2:
acount;
break;
case 1 when r.Next(1, 13) == 2:
bcount;
break;
}
}
Console.WriteLine($"a case hit {acount} times");
Console.WriteLine($"b case hit {bcount} times");
Вывод таков:
a case hit 0 times
b case hit 0 times
Теперь давайте попробуем уменьшить ваш диапазон в вашем операторе switch:
// ...
switch (r.Next(1, 20))
{
// ...
Теперь ваши результаты:
a case hit 26313397 times
b case hit 2191910 times
Итак, что мы пытаемся сказать вам в комментариях, Random.Next()
возвращает значение в диапазоне [0, 2147483647]
, которое почти вряд ли когда-либо вернет значение 1, которое требуется для продолжения ваших случаев переключения. Изменяя свой диапазон на гораздо более разумные значения, ваши шансы резко возрастают и, скорее всего, это то, чего вы хотите.