Better way to overload methods in C#

2019-08-25 17:59发布

So I have a method with some heavy overloading. However, the concept is fairly simple. "Accept any of there X data types as the first argument, then accept either of these two data types for the two remaining arguments". Is there a simpler way to do this? This is getting out of hand very fast.

    //Declared MyMethod(byte[], SpecializedArgumentType, SpecializedArgumentType) and a string-> SpecializedArgumentType  version of it.
    public static MyReturnType MyMethod(bool data, SpecializedArgumentType firstArg, SpecializedArgumentType secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(bool data, String firstArg, String secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(short data, SpecializedArgumentType firstArg, SpecializedArgumentType secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(short data, String firstArg, String secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(ushort data, SpecializedArgumentType firstArg, SpecializedArgumentType secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(ushort data, String firstArg, String secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(int data, SpecializedArgumentType firstArg, SpecializedArgumentType secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(int data, String firstArg, String secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(uint data, SpecializedArgumentType firstArg, SpecializedArgumentType secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(uint data, String firstArg, String secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(long data, SpecializedArgumentType firstArg, SpecializedArgumentType secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(long data, String firstArg, String secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(ulong data, SpecializedArgumentType firstArg, SpecializedArgumentType secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(ulong data, String firstArg, String secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(float data, SpecializedArgumentType firstArg, SpecializedArgumentType secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(float data, String firstArg, String secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(double data, SpecializedArgumentType firstArg, SpecializedArgumentType secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(double data, String firstArg, String secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(char data, SpecializedArgumentType firstArg, SpecializedArgumentType secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }
    public static MyReturnType MyMethod(char data, String firstArg, String secondArg)
    {
        return MyMethod(BitConverter.GetBytes(data), firstArg, secondArg);
    }

I have tried taking in an arbitrary object as the data type, but then I won't get the nice explicit data types in the auto-complete (Visual studio ctrl-space). Does this really have to be so verbose and hard to maintain? Maybe my approach to the initial problem needs revision?

2条回答
相关推荐>>
2楼-- · 2019-08-25 18:41

What about generics?

public static MyReturnType MyMethod<T>(T data, SpecializedArgumentType firstArg, SpecializedArgumentType secondArg)
{
    ...
}

That way you can just do:

ushort data = 42;
var result = MyMethod<ushort>(data,firstArg,secondArg);
查看更多
你好瞎i
3楼-- · 2019-08-25 18:52

You could make a data type that has implicit conversions from different types, and use that as the first parameter:

public class MyFirstParameter {

  public byte[] Bytes { get; private set; }

  private MyFirstParameter (byte[] bytes){
    Bytes = bytes;
  }

  public static implicit operator MyFirstParameter(int value) {
    return new MyFirstParameter(BitConverter.GetBytes(value));
  }

  public static implicit operator MyFirstParameter(long value) {
    return new MyFirstParameter(BitConverter.GetBytes(value));
  }

  // and a few more types

}

That will be a bunch of implicit operators, but then you only need two overloads of your method:

public static MyReturnType MyMethod(MyFirstParameter data, SpecializedArgumentType firstArg, SpecializedArgumentType secondArg) {
  return MyMethod(data.Bytes, firstArg, secondArg);
}

public static MyReturnType MyMethod(MyFirstParameter data, String firstArg, String secondArg) {
  return MyMethod(data.Bytes, firstArg, secondArg);
}

You can call the methods with any of the types that you have implicit conversions for, just as if there was a parameter with that type:

MyMethod(42, "", "");
查看更多
登录 后发表回答