Why Not Use Tuples?

I was wondering whether there was any particular reason why we don’t use tuples within the GetStat function? Currently, we’re retrieving a list of IModifierProvider twice. While this may be pre-optimization (which may not be relevant later), wouldn’t it be better to do something like:

public float GetStat(Stat stat)
{
    (float addMod, float perMod) = GetModifiers(stat);
    return (GetBaseStat(stat) + addMod) * (1 + perMod / 100);
}

private (float, float) GetModifiers(Stat stat)
{
    float addMod = 0.0f;
    float perMod = 0.0f;
    if (!shouldUseModifiers) return (addMod, perMod);

    foreach (IModifierProvider provider in GetComponents<IModifierProvider>())
    {
        foreach (float modifier in provider.GetAdditiveModifiers(stat))
        {
            addMod += modifier;
        }

        foreach (float modifier in provider.GetPercentageModifiers(stat))
        {
            perMod += modifier;
        }
    }
    return (addMod, perMod);
}
4 Likes

First of all, well done, this is a solid approach. Tuples are a fantastic feature, but it wasn’t introduced until C#7. While we did start the course with Unity 2018.3, a lot of folks didn’t even realize C#7 was available (prior to 2018.3, Unity was built on the Mono stack instead of the Roslyn stack, and so many beautiful language features were unavailable). If I recall, even in 2018.3, not all C#7 features were in yet.

Even with this, at this point in the series, it might be too soon in the coursework to formally introduce tuples. I still spend a lot of time talking students off the ledge after throwing them a Dictionary<Characterclass, Dictionary<Stat, float[]>>, or as I like to call it, the Turducken of data structures. :slight_smile:

That being said, it gives me an idea for some future enhancement tutorials. The type of thing to keep students engaged in the courses after they’ve completed the series.

2 Likes

or as I like to call it, the Turducken of data structures

ROFL! Yep. 100%
Maybe once my code-fu is a bit better, I’d welcome a new concept like tuples. They sound really powerful!

This looks quite neat although, in order to avoid going in twice, why not create a struct that holds both results and return the one struct instead? I improves readability and performance…

The things with tuples and the likes - for example multiple out parameters - is that it gets really messy really quickly…

Both tuples and encapsulating structs are good ways to return multiple values.

An alternate construction to this would be to give the values names in the declaration

(float addModifiers, float percentageModifiers) GetModifiers(Stat stat)

This avoids the extra code of creating

public struct ModifierBundle
{
     public float addModifiers;
     public float percentageModifiers;
}
ModifierBundle GetModifiers(Stat stat)

and still leaves clear (actually clearer) what the values are.

I would say this also reduces the overhead of creating a struct, but unlike a tuple with unnamed parameters, using a named tuple implicitly creates a behind the scenes struct, much like the second block of code.

Yes that makes sense, although my point was that if you have, say, 10 results to return. rather than going in the for loop 10 times, or return a 10-tuple, the struct will always be neater I think. If there is a guarantee that there would never be more than 2 or 3 results returned then yeah sure, tuple would be readable too

Outside of a database, if you have more than 10 results to return there may be other structural issues in the code… In any event, I wouldn’t use a tuple for more than 2 results.

Privacy & Terms