// Copyright (C) Stichting Deltares and State of the Netherlands 2025. All rights reserved.
//
// This file is part of Riskeer.
//
// Riskeer is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using Core.Common.Base.Data;
namespace Core.Common.TestUtil
{
///
/// Extension methods for .
///
public static class RandomExtensions
{
///
/// Generates a new pseudo-random number between and .
///
/// A pseudo-random number generator.
/// The lower limit of the new random number.
/// The upper limit of the new random number.
/// A new random number.
/// Thrown when is null.
/// Thrown when is larger than .
/// Thrown when the generated value is not finite.
public static double NextDouble(this Random random, double lowerLimit, double upperLimit)
{
if (random == null)
{
throw new ArgumentNullException(nameof(random));
}
if (lowerLimit > upperLimit)
{
throw new ArgumentException("lowerLimit is larger than upperLimit");
}
double difference = upperLimit - lowerLimit;
double randomValue = lowerLimit + random.NextDouble() * difference;
if (double.IsInfinity(randomValue) || double.IsNaN(randomValue))
{
string message = $"Creating a new random value with lower limit {lowerLimit} " +
$"and upper limit {upperLimit} did not result in a finite value.";
throw new NotFiniteNumberException(message, randomValue);
}
return randomValue;
}
///
/// Returns a random boolean value.
///
/// A pseudo-random number generator.
/// A new random boolean value.
/// Thrown when is null.
public static bool NextBoolean(this Random random)
{
if (random == null)
{
throw new ArgumentNullException(nameof(random));
}
return Convert.ToBoolean(random.Next(0, 2));
}
///
/// Returns a random value.
///
/// A pseudo-random number generator.
/// A new random .
/// Thrown when is null.
public static RoundedDouble NextRoundedDouble(this Random random)
{
if (random == null)
{
throw new ArgumentNullException(nameof(random));
}
return (RoundedDouble) random.NextDouble();
}
///
/// Generates a new pseudo-random number between and .
///
/// A pseudo-random number generator.
/// The lower limit of the new random number.
/// The upper limit of the new random number.
/// A new random .
/// Thrown when is null.
/// Thrown when is larger than .
/// Thrown when the generated value is not finite.
public static RoundedDouble NextRoundedDouble(this Random random, double lowerLimit, double upperLimit)
{
if (random == null)
{
throw new ArgumentNullException(nameof(random));
}
return (RoundedDouble) random.NextDouble(lowerLimit, upperLimit);
}
///
/// Returns a random value of .
///
/// The to use.
/// A pseudo-random number generator.
/// >A new random value of type .
/// Thrown when is null.
/// Thrown when is not an .
public static TEnum NextEnumValue(this Random random)
{
if (random == null)
{
throw new ArgumentNullException(nameof(random));
}
var enumValues = (TEnum[]) Enum.GetValues(typeof(TEnum));
return enumValues[random.Next(enumValues.Length)];
}
///
/// Returns a random value of from .
///
/// The to use.
/// A pseudo-random number generator.
/// A collection of valid enum values to return a random element from.
/// A random value of type from .
/// Thrown when any parameter is null.
/// Thrown when is empty or
/// of is not an .
public static TEnum NextEnumValue(this Random random, IEnumerable enumValues)
{
if (random == null)
{
throw new ArgumentNullException(nameof(random));
}
if (enumValues == null)
{
throw new ArgumentNullException(nameof(enumValues));
}
if (!typeof(TEnum).IsEnum)
{
throw new ArgumentException($"'{typeof(TEnum).Name}' is not an enum.");
}
if (!enumValues.Any())
{
throw new ArgumentException($"'{nameof(enumValues)}' cannot be an empty collection.");
}
return enumValues.ElementAt(random.Next(enumValues.Count()));
}
}
}