方法重载和类型转换

时间:2016-09-23 08:39:57

标签: c# type-conversion overloading

我有两种C#转换方法:

public int MyConvertToInteger(double x) {
  if (x > int.MaxValue) {
    return int.MaxValue;
  } else if (x < int.MinValue || double.IsNaN(x)) {
    return int.MinValue;
  } else {
    return (int)x;
  }
}

public int MyConvertToInteger(string str) {
  if (str == null) {
    return 0;
  }
  return str.Length;
}

和一个业务方法,每个参数有两种可能的类型,导致四个重载:

public int IntSum(int x, int y) { 
  unchecked {
    return x+y; 
  }
}

public int IntSum(int x, string y) { 
  int iy = MyConvertToInteger(y);
  return IntSum(x, iy);
}

public int IntSum(double x, int y) {
  int ix = MyConvertToInteger(x);
  return IntSum(ix, y);
}

public int IntSum(double x, string y) {
  int ix = MyConvertToInteger(x);
  return IntSum(ix, y);
}

这很烦人但很实用。但是,如果我要添加两个可能的类型的第三个参数,我们最多会有8个重载,IMO就会超出它的范围。

我想知道是否有办法以某种方式指定方法参数中可能的转换,以便我们不会获得大量的重载? (我对&#34;解决方案&#34;不感兴趣,它涉及更常规类型的参数,例如&#34; object&#34;,然后检查传入的任何类型。)

3 个答案:

答案 0 :(得分:1)

这不是一个好习惯,但请看一下

{{1}}

答案 1 :(得分:1)

您可以定义自定义复合类型,例如int或double可以表示为

    public class IntOrDouble
    {
        int i;
        double d;
        public enum MyType
        {
            None,
            Int,
            Double
        }
        MyType myType;
        public IntOrDouble(int i)
        {
            this.i = i;
            myType = MyType.Int;
        }
        public IntOrDouble(double d)
        {
            this.d = d;
            myType = MyType.Double;
        }
        public MyType GetReturnType()
        {
            return myType;
        }
        public int GetInt()
        {
            if (!myType.Equals(MyType.Int))
            {
                throw new Exception("wrong type");
            }
            return i;
        }
        public double GetDouble()
        {
            if (!myType.Equals(MyType.Double))
            {
                throw new Exception("wrong type");
            }
            return d;
        }
}

但这意味着你必须重写你的方法

    public int IntSum(IntOrDouble x, IntOrString y)

编辑通用版本(如果重复使用)

    public enum MyType
    {
        None,
        T1,
        T2
    }
    public class CompositeType<T1,T2>
    {
        T1 i;
        T2 d;
        MyType myType;
        public CompositeType(T1 i)
        {
            this.i = i;
            myType = MyType.T1;
        }
        public CompositeType(T2 d)
        {
            this.d = d;
            myType = MyType.T2;
        }
        public MyType GetReturnType()
        {
            return myType;
        }
        public T1 GetT1()
        {
            if (!myType.Equals(MyType.T1))
            {
                throw new Exception("wrong type");
            }
            return i;
        }
        public T2 GetT2()
        {
            if (!myType.Equals(MyType.T2))
            {
                throw new Exception("wrong type");
            }
            return d;
        }
        public object GetValue()
        {
            switch (myType)
            {
                case MyType.None:
                    throw new Exception("wrong type");
                case MyType.T1:
                    return GetT1();
                case MyType.T2:
                    return GetT2();
                default:
                    throw new Exception("wrong type");
            }

        }
    }

用法

    public int CompositeConversion<T>(CompositeType<int, T> x)
    {
        switch (x.GetReturnType())
        {
            case MyType.None:
                throw new Exception("wrong type");
            case MyType.T1:
                return x.GetT1();
            case MyType.T2:
                if (typeof(T) == typeof(double))
                {
                    return MyConvertToInteger((double)x.GetValue());
                }
                if (typeof(T) == typeof(string))
                {
                    return MyConvertToInteger((string)x.GetValue());
                }
                throw new Exception("wrong type");
            default:
                throw new Exception("wrong type");
        }
    }
    public int IntSum(CompositeType<int,double> x, CompositeType<int, string> y)
    {
        return CompositeConversion(x) + CompositeConversion(y);
    }

单元测试

        int test1 = t.IntSum(3.7, "55.9");
        int test2 = t.IntSum(
            new CompositeType<int,double>(3.7), 
            new CompositeType<int,string>("55.9")
            ); // test1 and test2 are both 7

答案 2 :(得分:1)

好吧,

  

我想知道是否有办法以某种方式指定可能的   方法参数中的转换,以便我们不会得到这个   大量过载?

没有。这在C#中是不可能的。

有时创建许多重载至关重要,尤其是在性能受到威胁时。我见过为一个方法创建了50个重载的项目。然而,可能的是从更通用的重载运行更严格的重载,换句话说Sum(x ,y, z)重载可以运行两个(x, y) + (y, z)所以没有必要在其中写入任何其他逻辑更通用的重载只是为了重用已经存在的重载。

唯一的另一个选择是接受params object[]并确定我们使用的类型,创建复合类型或使用dynamic