如何验证lambda表达式对空引用?

时间:2012-06-17 14:00:16

标签: c# lambda nullreferenceexception

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

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

稍后,在 T 类型的实例上调用所有代理,以查明此实例是否通过了过滤器,即,如果返回 true filterMember 已调用。

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

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

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

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

提前致谢!

3 个答案:

答案 0 :(得分:1)

我通常这样做:

AddFilterMember(
     x => {
           if(str == null) 
             throw new ArgumentNullException("str cannot be null");                     
           str.Contains((string)x)
          });

答案 1 :(得分: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作为示例。从那里,您只需尝试运行委托,看看它是否有效。返回bool以让调用者知道它是否成功完成。

请注意,调用委托可能会导致副作用。应该记录这种行为,以便呼叫者不会感到惊讶。

答案 2 :(得分:0)

相关问题和可能的答案:

Reflection - Get the list of method calls inside a lambda expression

但是如果没有try..catch实际执行,那么判断一个lambda表达式是否会在以后抛出是一个NP完全问题。

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

re:某些T没有默认值。

对于lambda的(T)null测试,可能是演员:try..catch,因为你特别询问NullReferenceException

-Jesse