在阅读了这篇 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`
}
}
Run Code Online (Sandbox Code Playgroud)
SomeClass.CreateItem可能因外部因素而失败.如果是,我想通知用户,如果不是,我想要执行一个动作.
C#编译器不希望我保持obj未初始化,所以我通常会分配null给它.
这感觉就像现在的'黑客',我的问题是:
上面的代码中是否存在设计缺陷?
如果有的话,在编译时如何处理引用,当我无法确定它们是否会在运行时指向现有对象时?
我会像这样重构代码:
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`
}
Run Code Online (Sandbox Code Playgroud)
"提取方法"是我最喜欢的重构.
// do something withobj`` 代码应该位于tryblock`内。
您想要做的是运行一些可能成功也可能不成功的代码,然后仅在前面的代码成功时才运行其他代码。这通常是一个非常强烈的迹象,表明其他代码是同一逻辑块的一部分,并且依赖于不存在异常。如果构造此对象时出现异常,您希望跳过此代码,这正是将其包含在块中所获得的行为try。