在Func<>中检查除零。呼叫

时间:2014-07-02 09:24:15

标签: c# func divide-by-zero

我正在尝试使用动态数学运算符处理二维数组。

这是有问题的方法:

public float[,] Calculate(int[,] a, int[,] b, Func<int,int,float> compute)
{
   int columns = a.GetLength(0);
   int rows = a.GetLength(1);
   float[,] result = new float[columns,rows];

   for(int i = 0; i < columns; i++)
   {
       for(int j = 0; j < rows; j++)
       {
            result[i,j] = compute(a[i,j], b[i,j]);      
       }
   }
   return result;
}

此方法的调用如下:

int[,] a = new int[2,3] { {2, 6, 19}, {3, -4, 25}};
int[,] b = new int[2,3] { {12, -2, 11}, {1, -11, 0}};

//1
float[,] c = Calculate(a, b, (x,y) => (x+y));
//2
float[,] c = Calculate(a, b, (x,y) => (x-y));
//3
float[,] c = Calculate(a, b, (x,y) => (x*y));
//4
float[,] c = Calculate(a, b, (x,y) => (x/y));

现在,虽然版本1到3完美无缺,但版本4迟早会抛出异常。 现在,处理此问题的一种方法是使用try catch块:

try 
{
    result[i,j] = compute(a[i,j], b[i,j]);      
}
catch(DivideByZeroException ex)
{
    result[i,j] = 0;
}

这看起来像我使用try catch进行流控制而我宁愿避免它(而且结果是错误的)。有没有办法在函数调用中检查除法运算符,如果运算符是/,检查第二个数组是否包含0并且只返回null?

2 个答案:

答案 0 :(得分:2)

通常的流量控制怎​​么样?一个if声明?

float[,] c;

if (b != 0)
    c = Calculate(a, b, (x,y) => (x/y));
else
    c = 0;

答案 1 :(得分:1)

这可能看起来有点奇怪的解决方案但是,您可以使用随机数测试您的函数并检查结果,如果结果总是1那么这意味着它是一个除法运算:

static bool IsDivision(Func<int, int, float> func)
{
    var rnd = new Random();

     return  Enumerable.Range(0, 10)
            .Select(x => rnd.Next(100))
            .All(x => Math.Abs(func(x, x) - 1) < 0.000001);
}

然后,在执行操作之前,您可以将func传递给此方法并执行适当的操作:

if(IsDivision(compute) &&  b.OfType<int>().Any(x => x == 0)) return null;

但我同意这不是一个很好的解决方案,例如这不适用于(x,y) => 1,但我认为你知道你在做什么,你不会将那种怪异的表达式传递给你的函数:)