AmazingMrBrock
AmazingMrBrock

Reputation: 197

using a method as variable

I have a method that outputs an integer:

public int Random6()
{
    int n = _r.Next (1, 7);
    return n;
}

And I have a loop that calls the method:

public static void DiceLoop()
{
    int result = 0;
    for(int i = 0; i < maxDice; i++)
    {
        result += Random6;
    }
    Console.WriteLine (result);
}

I want to be able to write the loop once and then pass it multiple methods using a variable name. For example:

public static void DiceLoop()
{
    int result = 0;
    for(int i = 0; i < maxDice; i++)
    {
        result += diceType;
    }
    Console.WriteLine (result);
}

Where diceType is a variable that will hold method names using an if function. I know I can't just have a have a method as a variable. I tried making diceType a string and passing that to the loop, but because Random6 gives out an int it won't work. I tried casting diceType into an int, but that doesn't work because it's casting the name of the method, not the number it spits out. How should I go about doing this? Do I just need an extra layer of variables and casting somewhere?

Upvotes: 1

Views: 197

Answers (2)

Michael Blackburn
Michael Blackburn

Reputation: 3229

To extend p.s.w.g's excellent answer, you can extend your dice roller to accept a number of sides as an input:

Func<int,int> getNextX = (x) => _r.Next(1,x+1);

Read "Func<int>" as "Function that returns an int," so "Func<int,int>" is a "Function that takes an int as a parameter and returns an int."

Then, DiceLoop would look like this:

public static void DiceLoop(Func<int,int> roller)
{
    int result = 0, maxDice = 20;
    for(int i = 1; i <= maxDice; i++)
    {
        result += roller(i);
    }
    Console.WriteLine (result);
}

This would give you the sum of one roll each from a 1 sided die (?) to a 20-sided die.

Upvotes: 2

p.s.w.g
p.s.w.g

Reputation: 149040

You can have a delegate as a variable. You can pass a Func<int> parameter into your DiceLoop function:

public static void DiceLoop(Func<int> getNext) 
{
    int result = 0;
    for(int i = 0; i < maxDice; i++)
    {
        result += getNext();
    }
    Console.WriteLine (result);
}

And then you can call this like:

DiceLoop(Random6);

This is just the easiest way to solve your particular case. If you wanted to say, create a variable and assign it reference to a delegate, you can do this:

Func<int> getNext = Random6;
DiceLoop(getNext);

You can even use lambda expressions (a.k.a anonymous functions) this way:

Func<int> getNext = () => _r.Next(1, 7);
DiceLoop(getNext);

Upvotes: 13

Related Questions