围绕“新”时的范围C# 中的 try/catch 语句

发布于 2024-11-10 17:17:06 字数 726 浏览 4 评论 0原文

这是声明新变量的“最佳实践”是什么的问题,我已经见过这种情况几次了。我有一个类,其构造函数读取配置文件,例如:

ConfigMgr config = new ConfigMgr(args[0]);

当然,如果您在没有该参数的情况下运行控制台应用程序,则会出现异常。如果我用 try/catch 包围该行,如下所示,我会收到错误“名称“config”在当前上下文中不存在”。可以理解。

try
{
    ConfigMgr config = new ConfigMgr(args[0]);
}
catch
{
    Console.WriteLine("Config file not specified or incorrect in format.  Exiting.");
    Console.ReadLine();
}

// Defaults
string aucomposingfile = config.getValue("aucomposingfile");
string nzcomposingfile = config.getValue("nzcomposingfile");
...etc

我可以在构造函数中分离出需要参数的部分 - 在 try/catch 块之外执行新的 ConfigMgr 部分,然后在 try/catch 中执行类似 config.LoadFile() 的操作。但我无法想象那些知情人士会这么做。

有什么想法吗?

谢谢!

This is a question of what the 'best practice' is for declaring new variables, and I've seen this situation a few times now. I have a class whose constructor reads a config file, eg:

ConfigMgr config = new ConfigMgr(args[0]);

Of course, if you run the console app without that argument, an exception results. If I surround that line with a try/catch as follows, I get the error 'The name 'config' does not exist in the current context'. Understandable.

try
{
    ConfigMgr config = new ConfigMgr(args[0]);
}
catch
{
    Console.WriteLine("Config file not specified or incorrect in format.  Exiting.");
    Console.ReadLine();
}

// Defaults
string aucomposingfile = config.getValue("aucomposingfile");
string nzcomposingfile = config.getValue("nzcomposingfile");
...etc

I could separate out the part that requires the argument in the constructor - do the new ConfigMgr part outside the try/catch block, then do something like config.LoadFile() in the try/catch. But I can't imagine that's what those in the know do.

Any thoughts?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜访吸血鬼 2024-11-17 17:17:06

你没有理由不能这样做:

ConfigMgr config = null;
try
{
    config = new ConfigMgr(args[0]);
}
catch ( /* catch a specific exception!! */ ) 
{
    //log it:
    Console.WriteLine("Config file not specified or incorrect in format.  Exiting.");

    //escape from here, because you don't want to continue:
    throw;    
}

string aucomposingfile = config.getValue("aucomposingfile");
string nzcomposingfile = config.getValue("nzcomposingfile");

当然,可以说更正确的方法可能是在尝试使用命令行参数之前检查它们,如果它们不满足你的要求,则抛出特定的异常 - 你依赖它们,所以首先验证它们。这比仅仅尝试使用它们并捕获异常具有更好的代码流程。这样,您的 catch 块就会更加关注配置文件更具体的问题,而不是处理命令行参数的问题。

There is no reason why you cannot do this:

ConfigMgr config = null;
try
{
    config = new ConfigMgr(args[0]);
}
catch ( /* catch a specific exception!! */ ) 
{
    //log it:
    Console.WriteLine("Config file not specified or incorrect in format.  Exiting.");

    //escape from here, because you don't want to continue:
    throw;    
}

string aucomposingfile = config.getValue("aucomposingfile");
string nzcomposingfile = config.getValue("nzcomposingfile");

Of course the arguably more correct way may be to check the command line arguments before attempting to use them, and throw a specific exception if they don't meet your requirements - you depend on them, so verify them first. This has a better code flow than just trying to use them and catching an exception. This way your catch block becomes more focused on problems more specific to the config file, rather than handling issues with the command line arguments as well.

梦忆晨望 2024-11-17 17:17:06

如果您需要在多个 try 块中访问变量,则需要在该块之前声明初始化该变量。只需声明并初始化为 null 就足够了。

Foo foo = null;
try 
{
    foo = DoSomethingToGetFoo();
}
catch (SpecificException ex)
{
    // do whatever, foo is accessible but may require null-checking
}
finally 
{
    // ditto 
}

// still accessible

显然,如果您希望在其他地方访问该变量,则必须在外部作用域中声明该变量。但初始化也是必要的,因为 C# 编译器需要证明变量在允许您使用之前已被初始化。如果“标准”初始值设定项在 try 的范围内,则编译器无法保证它会在稍后使用之前发生。

对于您自己的代码,您可以决定是否可以将需要对变量执行的所有操作包含在 try 中。如果是这样,显然将其范围限制在该块内。但在某些情况下,您需要更广泛的范围。 (请参阅:usingIDisposable 对象的扩展。)

If you need to access a variable in more than just a try block, you need to declare and initialize the variable before the block. Simply declaring and initializing to null is sufficient.

Foo foo = null;
try 
{
    foo = DoSomethingToGetFoo();
}
catch (SpecificException ex)
{
    // do whatever, foo is accessible but may require null-checking
}
finally 
{
    // ditto 
}

// still accessible

Obviously, declaring the variable in an outer scope is necessary if you wish to access it elsewhere. But initializing is also necessary, as the C# compiler will require proof that a variable has been initialized prior to allowing you to use it. If the "standard" initializer is in the scope of the try, the compiler cannot guarantee that it will have occured prior to being used later.

For your own code, you can decide if everything you need to do with a variable can be contained within the try. If so, obviously limit its scope to that block. But in some situations, you need a broader scope. (See: the expansion of using for IDisposable objects.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文