只是想知道这是否被认为是在C#中明确使用goto:
IDatabase database = null;
LoadDatabase:
try
{
database = databaseLoader.LoadDatabase();
}
catch(DatabaseLoaderException e)
{
var connector = _userInteractor.GetDatabaseConnector();
if(connector == null)
throw new ConfigException("Could not load the database specified in your config file.");
databaseLoader = DatabaseLoaderFacade.GetDatabaseLoader(connector);
goto LoadDatabase;
}
Run Code Online (Sandbox Code Playgroud)
我觉得这样可以,因为代码片段很小,应该有意义.当你想在处理异常后重试操作时,人们通常会从这样的错误中恢复吗?
编辑:那很快.回答几个问题并稍微澄清一下 - 这是一个过程的一部分,本质上是从一个不同类型的项目转换而来._userInteractor.GetDatabaseConnector()调用是确定用户是否要重试的部分(可能使用与正在加载的配置中的数据库不同的数据库).如果它返回null,则表明没有指定新的数据库连接,操作应该完全失败.
我不知道为什么我没有考虑使用while循环.它必须太接近下午5点.
编辑2:我查看了LoadDatabase()方法,DatabaseLoaderException如果失败则会抛出一个.我已经更新了上面的代码来捕获异常而不是异常.
编辑3:普遍的共识似乎是这样
Jos*_*osh 15
当你想在处理异常后重试操作时,人们通常会从这样的错误中恢复吗?
是的,在调用代码中.让这个方法的调用者决定是否需要重试逻辑.
更新:
澄清一下,如果你能真正处理它们,你应该只捕获异常.你的代码基本上说:
"我不知道发生了什么事,但无论我做了什么都会导致一切都爆炸......所以让我们再做一次."
捕获可以从中恢复的特定错误,并让其余的泡沫到达要处理的下一层.任何使它一直到顶部的异常代表了那时的真正错误.
更新2:
好吧,所以不要通过评论继续进行相当冗长的讨论,我将用半伪代码示例详细说明.
一般的想法是,您只需重新构建代码以执行测试,并更好地处理用户体验.
//The main thread might look something like this
try{
var database = LoadDatabaseFromUserInput();
//Do other stuff with database
}
catch(Exception ex){
//Since this is probably the highest layer,
// then we have no clue what just happened
Logger.Critical(ex);
DisplayTheIHaveNoIdeaWhatJustHappenedAndAmGoingToCrashNowMessageToTheUser(ex);
}
//And here is the implementation
public IDatabase LoadDatabaseFromUserInput(){
IDatabase database = null;
userHasGivenUpAndQuit = false;
//Do looping close to the control (in this case the user)
do{
try{
//Wait for user input
GetUserInput();
//Check user input for validity
CheckConfigFile();
CheckDatabaseConnection();
//This line shouldn't fail, but if it does we are
// going to let it bubble up to the next layer because
// we don't know what just happened
database = LoadDatabaseFromSettings();
}
catch(ConfigFileException ex){
Logger.Warning(ex);
DisplayUserFriendlyMessage(ex);
}
catch(CouldNotConnectToDatabaseException ex){
Logger.Warning(ex);
DisplayUserFriendlyMessage(ex);
}
finally{
//Clean up any resources here
}
}while(database != null);
}
Run Code Online (Sandbox Code Playgroud)
现在显然我不知道你的应用程序正在尝试做什么,这肯定不是一个生产示例.希望你能得到一般的想法.重构程序,以避免任何不必要的应用程序流中断.
干杯,乔希
也许我错过了一些东西,但为什么你不能使用while循环?如果您的代码提供了异常(这是一个错误的代码)功能,这将永远为您提供相同的循环.
IDatabase database = null;
while(database == null){
try
{
database = databaseLoader.LoadDatabase();
}
catch(Exception e)
{
var connector = _userInteractor.GetDatabaseConnector();
if(connector == null)
throw new ConfigException("Could not load the database specified in your config file.");
databaseLoader = DatabaseLoaderFacade.GetDatabaseLoader(connector);
//just in case??
database = null;
}
}
Run Code Online (Sandbox Code Playgroud)
如果你必须在普通代码中使用goto,那么你就错过了逻辑流程.你可以使用标准结构,if,while,等等.