有没有办法在LINQ中捕获导致异常的谓词?

时间:2012-11-01 14:29:19

标签: c# linq exception exception-handling

说我有一些陈述:

List<string> list = new List<string> {"1", "1", "2", "3", "4"};
try
{
    Class1 c = new Class1
        {
            s1 = list.Single(s => s == "1"),
            s2 = list.Single(s => s == "2"),
            s3 = list.Single(s => s == "3"),
            s4 = list.Single(s => s == "4")
        };
}
catch (InvalidOperationException ex)
{
    Console.WriteLine(ex.Message);
}

我肯定会转到catch块,并在此行显示错误“输入序列包含多个元素”:

s1 = list.Single(s => s == "1")

所以,我只是很好奇,有没有办法在catch块中显示错误谓词?这对于修复错误非常有用,如果我们会看到“有一个重复的元素”1“依次”。甚至是字符串格式的完整谓词。我可以以某种方式查看此信息并显示或记录它吗?

3 个答案:

答案 0 :(得分:4)

如果你真的需要有关谓词及其参数的信息,那么你可以创建自己的Single扩展方法(它将被调用而不是默认方法),这将实际包装默认的Single调用,但它会收到Expression(表示lambda表达式的表达式树)而不是Func(lambda表达式):

public static T Single<T>(this IEnumerable<T> sequence, 
                          Expression<Func<T, bool>> predicate)
{
    try
    {
        return sequence.Single(predicate.Compile());
    }
    catch (InvalidOperationException ex)
    {
        Console.WriteLine("Error on predicate " + predicate);
        throw;
    }            
}

在第s1 = list.Single(s => s == "1")行,它会抛出一个异常并写出相当错误的消息:

Error on predicate s => s == "1"

答案 1 :(得分:2)

不,抛出的异常(InvalidOperationException)是通用的,不会给出那种细节。堆栈跟踪将从Single()开始,而不显示传入的谓词。

如果您需要该级别的详细信息,您可以在单独的语句中设置属性,以便可以从堆栈跟踪中获取行号,或者您可以对数据进行“预先检查”以确保它符合你的独特条件。

答案 2 :(得分:-1)

List<string> list = new List<string> {"1", "1", "2", "3", "4"};
string sValue=null;
try
{
    sValue="1";
    Class1 c = new Class1
    {
       s1 = list.Single(s => s == sValue),

    };
}
catch (InvalidOperationException ex)
{
    Console.WriteLine("s => s == "+ sValue);
}