我目前正以不同的方式加载图片:
try {
// way 1
}
catch
{ // way 1 didn't work
try {
// way 2
}
catch
{
// etc.
}
}
我想知道是否有更清洁的方法来做到这一点。目前它不是问题,但如果我添加一些方法,它会变得混乱。
请注意,加载图像的方法也以同样的方式在try catch中,因为它可能不是图像
它基本上尝试了一堆东西来弄清楚你拖入应用程序的内容。
答案 0 :(得分:9)
您可以编写一个接受任意数量的委托的方法,尝试所有委托并在其中一个委托成功运行后停止。这将异常处理抽象到一个地方,并避免所有重复:
public static void AttemptAll(params Action[] actions)
{
var exceptions = new List<Exception>();
foreach (var action in actions)
{
try
{
action();
return;
}
catch (Exception e)
{
exceptions.Add(e);
}
}
throw new AggregateException(exceptions);
}
这允许你写:
AttemptAll(Attempt1, Attempt2, Attempt3);
如果方法计算结果,您可以创建第二个重载来处理它:
public static T AttemptAll<T>(params Func<T>[] actions)
{
var exceptions = new List<Exception>();
foreach (var action in actions)
{
try
{
return action();
}
catch (Exception e)
{
exceptions.Add(e);
}
}
throw new AggregateException(exceptions);
}
答案 1 :(得分:1)
假设加载图像的“不同方式”都会在失败时抛出异常,您可以迭代不同的方式,直到成功。下面的示例使用Function<Image>
来显示无参数函数,该函数在成功时返回图像。在您的具体示例中,您可能还有函数中的参数。
List<Function<Image>> imageLoaders = LoadTheListSomehow();
foreach (var loader in imageLoaders)
{
try
{
var image = loader();
break; // We successfully loaded the image
}
catch (Exception ex)
{
// Log the exception if desired
}
}
答案 2 :(得分:1)
那里的筑巢确实看起来没必要。我会隔离将图像加载到自己的私有方法中的每种方法,然后将这些方法称为循环中的委托,如下所示:
private static MyImage LoadFirstWay(string name) {
return ...
}
private static MyImage LoadSecondWay(string name) {
return ...
}
private static MyImage LoadThirdWay(string name) {
return ...
}
...
public MyImage LoadImage(string name) {
Func<string,MyImage>[] waysToLoad = new Func<string,MyImage>[] {
LoadFirstWay
, LoadSecondWay
, LoadThirdWay
};
foreach (var way in waysToLoad) {
try {
return way(name);
} catch (Exception e) {
Console.Error("Warning: loading of '{0}' failed, {1}", name, e.Message);
}
}
return null;
}