Define a static variable as a random value whenever called

I created a class for generating random values based on weights per value as follows:

public struct RandomizableField<T>
{
	public T value;
	public float weight;

	public RandomizableField(T value, float weight)
	{
		this.value = value;
		this.weight = weight;
	}
}

public class RandomizableSet<T>
{
	public List<RandomizableField<T>> set;

	public T GetRandomValue()
	{
		float totalWeight = 0.0f;
		float[] valueWeight = new float[set.Count];
		for(int i = 0; i < set.Count; i++)
		{
			valueWeight *= totalWeight;*

_ totalWeight += set*.weight;_
_
}*_

* float randomValue = Random.Range(0.0f, totalWeight);*
* for(int i = set.Count - 1; i >= 0; i–)*
* {*
_ if(randomValue >= valueWeight*)
{
return set.value;
}
}
return default(T); // Fallback in case List is empty*

* }*_

* public RandomizableSet(List<RandomizableField> values)*
* {*
* set = values;*
* }*
}
I’m currently utilizing this class to define values such as this (edited to save space in this post):
public static RS randomFloat =
new RS(new List<RF>()
{
* new RF(1.0f, 50.0f),*
* new RF(2.0f, 15.0f),*
* new RF(3.0f, 10.0f),*
* new RF(Random.Range(1.0f, 8.0f), 25.0f)*
});
To clarify, this generates one of the following:
1.0 (50% of the time)
2.0 (15% of the time)
3.0 (10% of the time)
Random between 1.0 and 8.0 (25% of the time)
When I generate this as a static variable, it only calculates the randomized value among them a single time upon script initialization. Therefore, my question is this:
Is there any (reasonable) way to randomize that randomized variable every time I call it as-is, or would that absolutely require type-specific variants of this generic class in order to support that?

What hexagonius meant was basically this:

 public static RS<System.Func<float>> randomFloat =
 new RS<float>(new List<RF<System.Func<float>>>()
 {
     new RF<System.Func<float>>(()=>1.0f, 50.0f),
     new RF<System.Func<float>>(()=>2.0f, 15.0f),
     new RF<System.Func<float>>(()=>3.0f, 10.0f),
     new RF<System.Func<float>>(()=>Random.Range(1.0f, 8.0f), 25.0f)
 });

Note to actually get a value you would have to do:

float v = GetRandomValue()();

No, the double parentheses is not an error. GetRandomValue will return a delegate and you have to invoke the delegate to make it return a value. If you generally want such a setup you can of course change your “RandomizableField” and “RandomizableSet” classes to directly use a Func<T> and call the delegate right inside your “GetRandomValue” method and return the value the delegate returned.

public struct RandomizableField<T>
{
    public System.Func<T> value;
    public RandomizableField(System.Func<T> value, float weight)
    // [ ... ]

and inside your “GetRandomValue” method:

if(randomValue >= valueWeight*)*

{
return set*.value();*
}
That way GetRandomValue would still just return a “T”.

It can be surprisingly challenging to locate something when you don’t know the right word for it. I had no idea that System.Func<> existed, since all my searches related to delegates never managed to obviously lead to it.

With that in mind, thank you, @Bunny83! Your answer was extremely clear and detailed and, moreover, resulted in exactly the kind of functionality I was looking for.