0

我有一个接受泛型委托作为参数的方法,并将其插入列表中:

public void AddFilterMember<T>(Func<T, bool> filterMember)
{
    filter.Add(filterMember);
}

稍后,所有的委托都在T类型的实例上被调用,以查明这个实例是否通过了过滤器,即是否为每个调用的filterMember返回true

我注意到可以传递一个无效的 lambda 表达式,如下所示:

string str = null;
AddFilterMember(x => str.Contains((string)x));

这显然会在调用时抛出异常,因为str字符串为空。所以我想知道在定义 lambda 表达式时针对空引用(除了它的参数)验证它的最佳方法吗?

我想一种选择是使用 T 的默认实例来调用它,但有时这是不可行的,因为 T 可能没有默认的无参数构造函数。

提前致谢!

4

3 回答 3

1

我通常这样做:

AddFilterMember(
     x => {
           if(str == null) 
             throw new ArgumentNullException("str cannot be null");                     
           str.Contains((string)x)
          });
于 2012-06-17T14:04:57.010 回答
1

这是一个可能的解决方案:

public bool AddFilterMember<T>(Func<T, bool> filterMember, T checkValue = default(T))
{
    try
    {
        filterMember(checkValue);
    }
    catch
    {
        return false;
    }
    filter.Add(filterMember);
    return true;
}

如果调用者知道这default(T)不起作用,但希望所有实际使用的值都起作用,他们可以指定 为checkValue示例。从那里,您只需尝试运行委托并查看它是否有效。返回Abool让调用者知道它是否成功完成。

请注意,调用委托可能会导致副作用。这种行为应该被记录下来,这样调用者就不会感到惊讶。

于 2012-06-17T14:10:57.683 回答
0

相关问题和可能的答案:

反射 - 获取 lambda 表达式中的方法调用列表

但是如果没有 try..catch 围绕实际执行,决定 lambda 表达式稍后是否会抛出是一个 NP 完全问题。

特别是如果,就像在您的示例中一样,lambda 引用的变量在每次执行表达式时可能为空,也可能不为空。如果 lambda 没有检查,那么它可能会抛出。

回复:一些 T 没有默认值。

也许是演员表:(T)null对于try..catchlambda 的测试,因为您专门询问NullReferenceException.

-杰西

于 2012-06-17T14:19:15.817 回答