我有一个接受通用委托作为参数的方法,并将其插入列表中:
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可能没有默认的无参数构造函数。
提前致谢!
答案 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