问题
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?
回答1:
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);
回答2:
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, "", "");
来源:https://stackoverflow.com/questions/15058314/better-way-to-overload-methods-in-c-sharp