1

I have this one generic class called Stat:

public class Stat<T> 
    {

        public string Name;
        public T Value;


        public Stat(string statName = "Stat")
        {
            Name = statName;
        }

        public Stat(T val)
        {
            Value = val;
        }
}

And I want to overload the + operator so that I can combine two stats, and get a stat object with the combined values (and same name as the stat object being returned to).

My idea was this:

public static Stat<T> operator+ (Stat<T> stat1, Stat<T> stat2)

        {
            Stat<T> result = new Stat<T>();
            //result.Value = stat1.Value + stat2.Value; //<- doesnt work
            return result;

        }

But, as you can see, I can't combine the values of the two stat objects. When I tried adding a where clause to this function, like so:

public static Stat<T> operator+ (Stat<T> stat1, Stat<T> stat2)
            where T: struct, IComparable, IComparable<T>, IEquatable<T>
        {
            Stat<T> result = new Stat<T>();
            //result.Value = stat1.Value + stat2.Value; //<- doesnt work
            return result;

        }

That's apparently a syntax error; says "the type or namespace 'where' cannot be found".

So, how do I have the values of the two stats be added? Also, how do I keep the name of the object being returned to intact? That last part is where I'm most lost on.

Edit: I learned how to get the values of the stats added a while ago, but keeping the name of one intact is the problem.

Also, this question is not a duplicate of this one. That one asks how to add two objects, resulting in their values being added in the new object. This one goes a step further by also asking how to keep one of the object's fields the same.

Tespy
  • 971
  • 2
  • 9
  • 18

1 Answers1

1

Apparently, there is currently no easy way to implement a generic add operator with C#. There are some workaround possible, which have trade-offs:

  • using dynamic
  • using compiled expressions
  • using IConvertible
  • using an abstract base class and derivations for each type

While this may all work, I would vote for the most simple approach: working with overloadable methods:

public static class StatHelper {

    public static Stat<int> Add(this Stat<int> l, Stat<int> r)
        => new Stat<int>(l.Value + r.Value);

    public static Stat<double> Add(this Stat<double> l, Stat<double> r)
                => new Stat<double>(l.Value + r.Value);
}

This works, is understandable to read and debug and you don't loose type safety or performance. Usage:

var s1 = new Stat<int>(5);
var s2 = new Stat<int>(6);
var s3 = s1.Add(s2);

Links to related questions:

ventiseis
  • 3,029
  • 11
  • 32
  • 49
  • 1
    Found a decent solution by using dynamic. Thanks! :> I might also use overloadable methods, like you suggested. – Tespy Aug 14 '17 at 21:07