我有一个示例代码,它调用 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)
如果您想知道哪个语句发出错误,您必须单独检查它们。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)