简体   繁体   English

如何处理未初始化的局部变量

[英]How to handle uninitialized local variables

After reading this Eric Lippert Article, I understand that the C# compiler doesn't like it if we leave local variables uninitialized. 在阅读了这篇 Eric Lippert文章后,我明白如果我们将局部变量保持为未初始化,C#编译器就不喜欢它了。

As I encounter this 'problem' from time to time, I looked at some of my old code and was able to weed out most of the situation where actually don't need uninitialized ( SomeClass obj = null ) local variables. 当我不时遇到这个“问题”时,我查看了一些旧的代码,并且能够清除大部分实际上不需要未初始化( SomeClass obj = null )局部变量的情况。

But I came up with a situation where I don't know how to refactor the code. 但我想出了一个我不知道如何重构代码的情况。

public void DoSomething(string foo) {   

    SomeClass obj; // = null; 

    try {
        obj = SomeClass.CreateItem(target);
    } catch(CustomException ex) {
        // notify UI of error
    }

    if (obj != null) {
        // do something with `obj`
    }
}

SomeClass.CreateItem may fail due to external factors. SomeClass.CreateItem可能由于外部因素而失败。 If it does, I want to notify the user, if not I want to perform an Action. 如果是,我想通知用户,如果不是,我想要执行一个动作。

The C# compiler doesn't want me to leave obj uninitialized, so I usually assign null to it. C#编译器不希望我将obj保留为未初始化,因此我通常会为其分配null

This feels like a 'hack' now and my question is: 这感觉就像现在的'黑客',我的问题是:

Is there a design flaw in the code above? 上面的代码中是否存在设计缺陷?

And if there is, how should I deal with references at compile time, when I can't determine if they are going to point to an existing object at run time? 如果有的话,在编译时如何处理引用,当我无法确定它们是否会在运行时指向现有对象时?

I would refactor the code like this: 我会像这样重构代码:

private SomeClass TryToCreateItem()
{
    try 
    {
        return SomeClass.CreateItem(target);
    } 
    catch(CustomException ex) 
    {
        // notify UI of error
    }
    return null;
}

public void DoSomething(string foo) 
{ 
    SomeClass obj = TryToCreateItem(); 
    if (obj != null) {
      // do something with `obj`
    }

"Extract method" is my favourite refactoring. “提取方法”是我最喜欢的重构。

The // do something with obj`` code should be inside the try block` . // do something with obj``代码// do something with操作应该在try块中

What you're trying to do is run some code that may or may not succeed, and then run some other code only if the previous code succeeded . 你要做的是运行一些可能成功或不成功的代码,然后只有在前面的代码成功时运行其他代码。 That's generally a very strong sign that the other code is a part of the same logical block that is dependent on there not being an exception. 这通常是一个非常强烈的信号,即其他代码是同一逻辑块的一部分,依赖于没有异常。 If there's an exception constructing this object you want this code to be skipped, which is exactly the behavior that you get by including it in the try block. 如果构造此对象存在异常,则需要跳过此代码,这正是将其包含在try块中所获得的行为。

You could refactor it to encapsulate all your code within the try/catch related to that object and if you really do need to do something if it fails then you can use a bool to relate that to the rest of your code: 您可以重构它以将所有代码封装在与该对象相关的try / catch中,如果确实需要执行某些操作,那么您可以使用bool将其与其余代码相关联:

    public void DoSomething(string foo)
    {

        bool failedCreation = false;

        try
        {
            SomeClass obj = SomeClass.CreateItem(target);
        }
        catch (CustomException ex)
        {
            // notify UI of error
            failedCreation = true;
        }

        if (failedCreation)
        {
            // do other stuff.
        }
    }

But this doesn't look like what you have in mind. 但这看起来并不像你的想法。 I would just encapsulate everything within the try/catch and be done with it. 我只是将try / catch中的所有内容封装起来并完成它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM