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

时间:2015-07-08 18:27:10

标签: c# clr

阅读this Eric Lippert文章后,我了解如果我们将本地变量保持未初始化,C#编译器不会喜欢它。

当我遇到这个'问题'我不时地查看了一些旧代码,并且能够清除大部分实际上不需要未初始化(SomeClass obj = null)局部变量的情况。

但我想出了一个我不知道如何重构代码的情况。

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可能会失败。如果是,我想通知用户,如果不是,我想要执行操作。

C#编译器不希望我将obj保持未初始化状态,因此我通常为其分配null

这感觉像是一个' hack'现在,我的问题是:

上面的代码中是否存在设计缺陷?

如果有的话,我应该如何在编译时处理引用,何时我无法确定它们是否会在运行时指向现有对象?

3 个答案:

答案 0 :(得分:9)

我会像这样重构代码:

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`
    }

"提取方法"是我最喜欢的重构。

答案 1 :(得分:2)

// do something with obj``代码应位于try块`内。

您尝试执行的操作是运行一些可能成功或可能不成功的代码,然后仅在前一代码成功时运行其他代码。这通常是一个非常强烈的信号,即其他代码是同一逻辑块的一部分,依赖于没有异常。如果构造此对象有异常,则需要跳过此代码,这正是将其包含在try块中所获得的行为。

答案 2 :(得分:0)

您可以重构它以将所有代码封装在与该对象相关的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.
        }
    }

但这看起来并不像你想到的那样。我将封装try / catch中的所有内容并完成它。