Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return 2 or 3 values with Tuple?

Tags:

c#

return

tuples

So I'm making a silly game in c# but I'm a bit stuck here.

I'm trying to return either 2 values or either 3 values, depends on the rules of the game.

I need to know how I can return different amounts of values in only one function. Like sometimes I need to return 3 values and sometimes 7 values... in one function.

The error is with the variable tuple of course, as I can't return less than 3 values..

public Tuple<int, int, int> movepion(schaken.pion pion, int row, int column)
{
    int row2 = row + 1;

    //posities berekenen
    if (pion.kleur == Color.Blue)
    {
        if (pion.volgnr == 0) { row++; row2++; }
        else { row++; }
    }
    else
    {
    }

    // declaration
    var tuple = new Tuple<int, int>(row, column);
    var tuple2 = new Tuple<int, int, int>(row, row2, column);

    // what position?
    if (pion.volgnr == 0)
    {
        pion.volgnr = pion.volgnr + 1;
        return tuple2;
    }
    else
    {
        return tuple;
    }
}
like image 986
Thibaut Avatar asked Dec 14 '22 04:12

Thibaut


2 Answers

Return a collection instead of a Tuple<>

public IEnumerable<int> movepion(schaken.pion pion, int row, int column)
{
    IEnumerable<int> result;
    bool return2Items = false; //Some logic part to decide how many items to return
    if(return2Items)
        result = new List<int> { 1, 2 };
    else
        result = new List<int> { 1, 2, 3 };

   return result;    
}

After the better understanding the comments I'd recommend to create an object MoveOption and that the function will return IEnumerable<MoveOption>

public class MoveOption
{
    public int X { get; set; }
    public int Y { get; set; }
}

Then in your function:

public IEnumerable<MoveOption> movepion(schaken.pion pion, int row, int column)
{
    List<MoveOption> options = new List<MoveOption>();

    if(/*some condition*/)
    {
        options.Add(new MoveOption{ X = 1, Y = 2 });
    }

    if(/*some condition*/)
    {
        options.Add(new MoveOption{ X = 5, Y = 7 });
    }

    //Rest of options

    return options;
}

Then if you want to take it one step forward you can use inheritance and:

public interface IMoveOptionCalcumator
{
    public MoveOption Calculate(/*input*/);
}

public class MoveOptionX : IMoveOptionCalcumator
{
    public MoveOption Calculate(/*input*/) { /*some implementation*/ }
}

And in your function:

public class YourClass
{
    public IEnumerable<IMoveOptionCalcumator> MoveOptionCalculators { get; set; }

    public YourClass()
    {
        // Initialize the collection of calculators 
        // You can look into Dependency Injection if you want even another step forward :)
    }


    public IEnumerable<int> movepion(schaken.pion pion, int row, int column)
    {
        List<MoveOption> options = new List<MoveOption>();
        foreach (var item in MoveOptionsCalculators)
        {
            var result = item.Calculate(/*input*/);
            if(result != null)
            {
                options.Add(result);
            }
        }
        return options;
    }
}
like image 166
Gilad Green Avatar answered Dec 23 '22 12:12

Gilad Green


Try changing the return type to

Tuple<int, int, int?>

That way you would have

var tuple = new Tuple<int, int, int?>(row, column, null);

Anyway, I think it would be best to clear the semantics of the method and probably have it return a meaningfull custom data type.

like image 37
José Margaça Lopes Avatar answered Dec 23 '22 11:12

José Margaça Lopes