代码之家  ›  专栏  ›  技术社区  ›  user366312

如何使用泛型将两个函数合并为一个函数?

  •  -2
  • user366312  · 技术社区  · 6 年前

    假设我有以下功能:

    public int Compute(int a, int b, int c)
    {   
        return (a + b +c)/3;
    }
    
    public double Compute(double a, double b, double c)
    {
        return ((a + b + c) / 3.0) / 209;
    }
    

    我希望差别是明显的。双倍值需要除以209(常量值),而整数不需要。

    使用泛型将这两个函数组合成一个函数的最佳方法是什么?

    4 回复  |  直到 6 年前
        1
  •  0
  •   Ivan García Topete    6 年前

    你不应该用泛型来做,但是你可以测试 a , b c int 然后选择您的操作:

    private double Compute(double a, double b, double c)
    {
        /*         check if a, b and c are integers         int if true          double if false    */
        return (a % 1 == 0 && b % 1 == 0 && c % 1 == 0) ? (a + b + c) / 3 : ((a + b + c) / 3.0) / 209;
    }
    
    [TestMethod()]
    public void Int()
    {
        int a = 1;
        int b = 2;
        int c = 3;
        int result = (int)Compute(a, b, c);
    
        int expected = (1 + 2 + 3) / 3;
    
        Assert.AreEqual(expected, result);
    }
    
    [TestMethod()]
    public void Double()
    {
        double a = 1.1;
        double b = 2.2;
        double c = 3.3;
        double result = Compute(a, b, c);
    
        double expected = ((1.1 + 2.2 + 3.3) / 3.0) / 209;
    
        Assert.AreEqual(expected, result);
    }
    

    两项测试都通过了

        2
  •  2
  •   Sergey Prosin    6 年前

    我不确定这是否有意义。 泛型是避免为不同对象类型编写类似代码的方法。

    但是在您的例子中,我没有看到任何类似的代码可以被通用化,因此保持函数不同可以更好地解决任务。

        3
  •  1
  •   CodingYoshi    6 年前

    简短的回答

    你不能把它变成一个函数。

    冗长的回答

    唯一常见的代码是:

    return (a + b +c)/
    

    您可以使用泛型并尽可能做到这一点(对于C#)是不可能的:

    public static T Compute<T>(T a, T b, T c, T divisorSmall, int divisor) 
    {
        return ((a + b + c) / divisorSmall) / divisor;
        // Results in compiler error: Error CS0019  Operator '+' cannot be 
        // applied to operands of type 'T' and 'T'  
    }
    

    像这样使用:

    Compute(1, 2, 3, 3, 1); // For integers
    Compute(1.0, 2.0, 6.0, 3.0, 209); // For doubles
    

    但你不能这么做是因为 you cannot restrict the type T to support arithmetic operation restrict T to be numeric .

    另外,即使这是可能的,在这种特定的情况下也不会得到太多好处,因为在我的假设解决方案中,使用起来有多笨拙。

        4
  •  0
  •   Antoine V    6 年前

    我有个主意。我可以创建一个方法泛型来接收 Delegate 每种情况 int double . 这个版本的小提琴管用 https://dotnetfiddle.net/Q15bYK

        public static void Main()
        {   
            Func<double,double,double,double> x = (d1,d2,d3) => {return ((d1 +d2 + d3)/ 3.0) / 209;};
    
            Func<int,int,int,int> y = (i1,i2,i3) => {return (i1 + i2 + i3)/ 3;};
    
            var rsDouble = Compute<double>(1.0,2.0,3.0,x);
            Console.WriteLine(rsDouble);
    
            var rsInt = Compute<int>(1,2,3,y);
            Console.WriteLine(rsInt);
    
        }
    
        public static T Compute<T>(T a, T b, T c, Func<T,T,T,T> action)
        {
            return action(a,b,c);
        }
    

    但我的答案似乎使情况变得复杂,我同意其他答案,泛型用于为不同的对象类型编写相似的代码,而不是为每个参数编写不同的代码。