SingleOrDefault 异常处理

Ale*_*lex 3 .net c# linq

我有一个示例代码,它调用 SingleOrDefault 方法 3 次,并在任何序列具有多个匹配元素时记录异常。

如果我想检查此代码的哪一部分引发异常,问题就开始了。

是否可以从此异常中获取一些有用的信息,例如谓词参数或集合类型以进行更详细的跟踪?

像这样 -序列包含多个匹配元素。集合 IEnumrable|ParamType| param {谓词参数 toString()}

 public void GetSingleOrDefaultTest(){

    try{

        var user = Users.SingleOrDefault(e => e.Id == 1);

        var profile = UserProfiles.SingleOrDefault(e => e.Id == 1);

        var profile2 = UserProfiles.SingleOrDefault(e => e.Id == 2);


    } catch(InvalidOperationException ex){
        Log(ex);
    }

}
Run Code Online (Sandbox Code Playgroud)

abt*_*bto 5

如果您想知道哪个语句发出错误,您必须单独检查它们。InvalidOperationException在每次SingleOrDefault调用时捕获 ,并将其包装在一个新的异常中,您可以填充附加信息。

try
{
    User user;
    UserProfile profile;
    UserProfile profile2;

    try
    {
        user = Users.SingleOrDefault(e => e.Id == 1);
    }
    catch (InvalidOperationException ex)
    {
        throw new InvalidOperationException("User lookup for Id = 1 failed", ex);
    }

    try
    {
        profile = UserProfiles.SingleOrDefault(e => e.Id == 1);
    }
    catch (InvalidOperationException ex)
    {
        throw new InvalidOperationException("User profile lookup for Id = 1 failed", ex);
    }

    try
    {
        profile2 = UserProfiles.SingleOrDefault(e => e.Id == 2);
    }
    catch (InvalidOperationException ex)
    {
        throw new InvalidOperationException("User profile lookup for Id = 2 failed", ex);
    }

    // work with user, profile and profile2
}
catch(InvalidOperationException ex)
{
    Log(ex);
}
Run Code Online (Sandbox Code Playgroud)

编辑:

您还可以通过以下方式封装单个尝试捕获

private static T GetSingleOrDefault<T>(IEnumerable<T> collection, Expression<Func<T, bool>> predicate)
{
    try
    {
        return collection.SingleOrDefault(predicate.Compile());
    }
    catch (InvalidOperationException e)
    {
        var message = string.Format(
            "{0} (Collection: {1}, param: {2})",
            e.Message,
            collection.GetType(),
            predicate);

        throw new InvalidOperationException(message);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样你的代码看起来像

try
{
    var user = GetSingleOrDefault(Users, e => e.Id == 1);

    var profile = GetSingleOrDefault(UserProfiles, e => e.Id == 1);

    var profile2 = GetSingleOrDefault(UserProfiles, e => e.Id == 2);

    // work with user, profile and profile2
}
catch(InvalidOperationException ex)
{
    Log(ex);
}
Run Code Online (Sandbox Code Playgroud)

这会产生类似的消息

System.InvalidOperationException:序列包含多个匹配元素(集合:IEnumerable`1[User],参数:e => e.Id == 1)