在if语句中声明变量

5
在我正在编写的相对简单的C#程序中,我正在尝试创建一个事件处理程序函数,以处理多个来源,如下所示:
private void fooHandler(object sender, RoutedEventArgs e)
{
    fooObject objectFoo = (fooObject)sender;
    if (objectFoo.name == "bla1"){
        bla1Window bla = new bla1Window();
    }
    if (objectFoo.name == "bla2"){
        bla2Window bla = new bla2Window();
    }
    .
    .
    .
    else{
        //default stuff happens
    }
bla.Left = this.Left
bla.Top = this.Top
bla.Show();
this.Close();
}

该函数用于窗口切换。 问题在于变量一旦退出if语句就会超出作用域。我这样做是因为,查看我定义的处理每个事件的一系列函数时,它们都是相同的,除了一个变量声明外。有没有办法让这个工作,或者我只能坚持为每个事件处理程序使用一个函数?
6个回答

9
如果bla1Windowbla2Window都共享一个基类或接口,你可以这样引用它们。在这种情况下,看起来你只是访问Window的属性,所以你可以这样做:
Window window = null;
fooObject objectFoo = (fooObject)sender;
if (objectFoo.name == "bla1"){
    window = new bla1Window();
}
else if (objectFoo.name == "bla2"){
    window = new bla2Window();
}
.
.
.
else{
    //default stuff happens
}

window.Left = this.Left
window.Top = this.Top
window.Show();
this.Close();

这也可以工作,但为什么比仅使用var window更好呢? - Will
2
@Will 因为它有效啊 ;-) var 需要被赋予一个初始值,以便它“知道类型”。var objectFoo = (object)null; 只有这么多用处啦 ;-) dynamic 没有这个问题,但是... - user166390
@pst - 虽然我认为直接使用 Window 是正确的方式,但是使用 var objectFoo = (Window)null; 也可以达到同样的效果。 - Chris Dunaway
@Chris:那只是因为你仍然通过强制转换向编译器提供类型。就我个人而言,在任何代码审查中,我都会拒绝那行代码(并与编写它的开发人员进行认真的交谈),因为这比只需执行“Window objectFoo = null;”更费力且不够清晰。 - Reed Copsey
@Reed:我完全同意,我只是指出它会起作用。 - Chris Dunaway

2

请考虑:

private void fooHandler(object sender, RoutedEventArgs e)
{
    fooObject objectFoo = (fooObject)sender;
    Window bla; // a super-type or interface, don't assign a value here
                // so there will be a compile error if it was
                // forgotten below
    if (objectFoo.name == "bla1"){
        bla = new bla1Window();
    } else if (objectFoo.name == "bla2"){
        bla = new bla2Window();
    } else {
        // just make sure to assign to bla
        // or there will a compiler error later
    }
    bla.Left = this.Left
    bla.Top = this.Top
    bla.Show();
    this.Close();
}

我通常会这样写,但是:
Window CreateFromName(string name) {
    if (name == "bla1"){
        return new bla1Window();
    } else if (name == "bla2"){
        return new bla2Window();
    } else {
        // just make sure to return a value
        // or there will a compiler error later
    }
}

private void fooHandler(object sender, RoutedEventArgs e)
{
    fooObject objectFoo = (fooObject)sender;
    Window bla = CreateFromName(objectFoo.name);
    bla.Left = this.Left
    bla.Top = this.Top
    bla.Show();
    this.Close();
}

愉快编码。


0
解决方案就是将变量提升到需要在 if 语句之后使用的作用域中。这很简单。但我建议你尝试重构代码,或者至少发布真实代码,这样我们可以试一下。当你有一堆代码在多个 if 语句中重复出现时,通常可以简化为一个或两个方法。
private void fooHandler(object sender, RoutedEventArgs e)
{
    fooObject objectFoo = (fooObject)sender;

    // use the base class and work with that.
    // all windows have the properties you use 
    // below, so there is no need to declare it
    // as a more specific type.
    blahWindow bla = null; 
    if (objectFoo.name == "bla1"){
        bla = new bla1Window();
    }
    if (objectFoo.name == "bla2"){
        bla = new bla2Window();
    }
    .
    .
    .
    else{
        //default stuff happens
        bla = new BlahDefault();
    }

    // 'bla' cannot be nbull here if each branch above assigns it
    bla.Left = this.Left
    bla.Top = this.Top
    bla.Show();
    this.Close();
}

0

所有的窗口都应该有一个共同的父级。使用子构造函数并将其分配给父对象,可以在“if”语句之外单独声明。

private void fooHandler(object sender, RoutedEventArgs e)
{
    Window bla = null;
    fooObject objectFoo = (fooObject)sender;
    if (objectFoo.name == "bla1"){
        bla = new bla1Window();
    }
    if (objectFoo.name == "bla2"){
        bla = new bla2Window();
    }
    .
    .
    .
    else{
        //default stuff happens
    }
    if(bla != null)
    {
        bla.Left = this.Left
        bla.Top = this.Top
        bla.Show();
        this.Close();
    }
}

0

我认为你应该确保在if语句之前声明变量。 这样应该可以解决你的问题。 示例

public string IfStatement()
{   
    string myValue = null;

    bool condition = true;
    if (condition)
    {
        myValue  = "something";
    }
    else
    {
        myValue  = "something else";
    }
    return myValue;
}

0

你真的想把这个变成一个接口,并在 if 代码之前声明接口。看起来下面调用的所有 bla 方法都是通用的,这是一个很好的接口候选(如果更合适,则为抽象类)。

事实上,在这个文件中最好根本不要切换,而是将其放入工厂或其他东西中。如果你决定走这条路,互联网上有很多相关信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接