你知道一种比下面更好的方式(更漂亮)抛出异常吗?
public long GetPlaylistId(long songInPlaylistId)
{
var songInPlaylist = service.GetById(songInPlaylistId);
return songInPlaylist
.With(x => x.Playlist)
.ReturnValueOrException(x => x.Id,
new ArgumentException(
"Bad argument 'songInPlaylistId'"));
}
Monadic扩展方法:
public static TResult With<TInput, TResult>(this TInput obj,
Func<TInput, TResult> evaluator)
where TInput : class
where TResult : class
{
return obj == null ? null : evaluator(obj);
}
public static TResult ReturnValueOrException<TInput, TResult>(
this TInput obj, Func<TInput, TResult> evaluator, Exception exception)
where TInput : class
{
if (obj != null)
{
return evaluator(obj);
}
throw exception;
}
答案 0 :(得分:3)
如果尝试获取没有播放列表的播放列表是有效的,那么您不应该抛出异常,而应该返回一个特殊值,这意味着&#34;未找到&#34;相反(例如,0或-1取决于播放列表ID的工作方式)。
或者,您可以编写TryGetPlaylistId()
方法,其工作方式与Microsoft的TryXXX()
方法类似(例如SortedList.TryGetValue()
),例如:
public bool TryGetPlaylistId(long songInPlaylistId, out long result)
{
result = 0;
var songInPlaylist = service.GetById(songInPlaylistId);
if (songInPlaylist == null)
return false;
if (songInPlaylist.Playlist == null)
return false;
result = songInPlaylist.Playlist.Id;
return true;
}
这种方法的一个小问题是,您在模拟诊断问题时可能会使用的信息模糊不清。也许添加Debug.WriteLine()
或其他形式的日志记录是有用的。关键是,您无法区分未找到播放列表ID的情况,以及找不到播放列表ID但不包含播放列表的情况。
否则,您可以抛出一个包含更多信息的异常,例如:
public long GetPlaylistId(long songInPlaylistId)
{
var songInPlaylist = service.GetById(songInPlaylistId);
if (songInPlaylist == null)
throw new InvalidOperationException("songInPlaylistId not found: " + songInPlaylistId);
if (songInPlaylist.Playlist == null)
throw new InvalidOperationException("Playlist for ID " + songInPlaylistId " has no playlist: ");
return songInPlaylist.Playlist.Id;
}
可能的情况是,在播放列表中找不到该歌曲是有效的,但找到没有播放列表的歌曲是无效的,在这种情况下,您将在第一种情况下返回一个特殊值,在第二种情况下抛出异常,例如:
public long GetPlaylistId(long songInPlaylistId)
{
var songInPlaylist = service.GetById(songInPlaylistId);
if (songInPlaylist == null)
return -1; // -1 means "playlist not found".
if (songInPlaylist.Playlist == null)
throw new InvalidOperationException("Playlist for ID " + songInPlaylistId " has no playlist: ");
return songInPlaylist.Playlist.Id;
}
无论如何,我个人认为你的扩展方法只是模糊了代码。
答案 1 :(得分:0)
try{
if (obj != null)
{
return evaluator(obj);
}
}
catch(Exception ex)
{
throw;
}
return obj;
除非陷入某些人,否则不应该抛出错误。最好在给定的情况下返回null并在您的调用代码中处理它:
答案 2 :(得分:0)
如果我班上有多个这样模棱两可的方法,会发生什么?为任何方法制定不同的规则是非常困难的。最后你会感到困惑。 您对此解决方案有何看法?
public class ApplicationResponse
{
public IList<string> Errors { get; set; }
public dynamic Data { get; set; }
public bool HasErrors()
{
return Errors != null && Errors.Any();
}
}
public ApplicationResponse GetPlaylistId(long songInPlaylistId)
{
var songInPlaylist = service.GetById(songInPlaylistId);
if (songInPlaylist == null)
{
return new ApplicationResponse { Errors = new[] { "Song was not found." } };
}
if (songInPlaylist.Playlist == null)
{
return new ApplicationResponse { Errors = new[] { "Playlist was not found." } };
}
return new ApplicationResponse { Data = songInPlaylist.Playlist.Id };
}
public HttpResponseMessage SomeRequest([FromUri] songInPlaylistId)
{
var response = appService.GetPlaylistId(long songInPlaylistId);
if (response.HasErrors())
{
// reply with error status
}
// reply with ok status
}
在这种情况下,我可以将所有错误发送给客户。