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



假设我有以下函数:

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(常数值(,而整数则不然。

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

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

但在你的情况下,我看不到任何类似的代码可以被泛化,所以保持函数的不同可以更好地解决任务。

简短回答

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

长答案

你唯一的通用代码是:

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

但您不能这样做,因为您不能将类型T限制为支持算术运算,也不能将T限制为数字。

此外,即使这是可能的,在这种特定的情况下也不会有太多收获,因为看看我假设的解决方案中的用法看起来有多笨拙。

你不应该用泛型来做,但你可以测试abc是否是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);
}

两项测试均通过

我有个主意。我可以创建一个方法泛型,它为每种情况intdouble接收一个Delegate。这个版本的小提琴工作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);
}

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

最新更新