Search code examples
c#overloadingstrong-typinggeneric-method

Creating a method that accepts both Vector2 and Vector3 arguments in C#


I'm starting with C# and having trouble writing a method that accepts both Vector2 and Vector3 arguments in C#.

Generic methods looked like the way to go, but I can't make it work just yet. Here's what I tried:

static void GetNoisePosition<T>(ref T position, float offset, float scale) where T : IEquatable<T>
{
    position += position.GetType().one * (offset + 0.1f);
    position *= scale;
}

I dont really want to have 2 versions of GetNoisePosition, each taking a vector type, as I dont want to duplicate the logic, and it'd be hard to create another method that would share some of this logic.

So, the issue is that I want to call the one method on the class of type T, but it's telling me that I can't.

Can I get access to the class via the position instance and call one on it?


Solution

  • Getting the type of the vector, and the operator methods using reflection:

    public static void CalculateNoisePosition<T>(ref T position, float offset, float scale)
    {
      Type vector = position.GetType();
      MethodInfo add = vector.GetMethod("op_Addition", new[] {typeof(T), typeof(T)});
      MethodInfo multiply = vector.GetMethod("op_Multiply", new[] {typeof(T), typeof(float)});
    
      T one = (T) vector.GetProperty("one").GetValue(null);
    
      position = (T) add.Invoke(null, new object[] {position, multiply.Invoke(null, new object[] {one, offset + 0.1f})});
      position = (T) multiply.Invoke(null, new object[] {position, scale});
    }
    

    Note that if you call this method with T being anything else other than Vector2 or Vector3, you will most likely get a NullReferenceException.

    As always when there's reflection involved, please profile the code and decide whether it's worth it to use this approach rather than write 2 almost identical methods.