【问题标题】:C# : Using statement and this keywordC#:使用语句和 this 关键字
【发布时间】:2020-07-22 14:00:02
【问题描述】:

在想使用 using 语句时,遇到了一个我不明白的场景:

private void RoomMealHistory_Click(object sender, EventArgs e)
    {
        MealRoomPlanning fMealRoomPlanning = new MealRoomPlanning(true);
        fMealRoomPlanning .MdiParent = this;
        fMealRoomPlanning.Show(); 
    }

此代码工作正常,我的窗口是 MdiChild。

但是,下面的代码不起作用:

private void RoomMealHistory_Click(object sender, EventArgs e)
    {
        using (MealRoomPlanning fMealRoomPlanning = new MealRoomPlanning(true))
        {
            MdiParent = this;
            fMealRoomPlanning.Show();
        }
    }

ArgumentException: '表单不能同时是 MDI 子级和 MDI 父级。

我也尝试用 this 替换它。ParentForm 不再起作用了。

这个范围有问题吗?

【问题讨论】:

  • 第二种情况下不应该是fMealRoomPlanning.MdiParent = this;吗?
  • MdiParent 之前有一个隐含的this。像这样:this.MdiParent = this;
  • 您似乎对 using 的用途感到困惑。它基本上创建了一个try-finally,它将确保using 中的对象被放置在范围的末尾。你似乎想要的是调用“对象初始化器”,它的格式是new Thing(){ Prop = value, OtherProp = value,};
  • 您还可以扩展MealRoomPlanning 的构造函数以在其中传递一个可选的MDIParent。然后你可以使用 using 块,一旦它关闭就自动摆脱控件并让你的代码简洁

标签: c# this using


【解决方案1】:

在您的第一个 sn-p 中,您设置了 fMealRoomPlanning 的 MdiParent-Property。

在您的第二个 sn-p 中,您将 MdiParent 设置为您自己的类实例 (this.MdiParent)。

你应该在你正在使用的对象上设置它:

private void RoomMealHistory_Click(object sender, EventArgs e)
    {
        using (MealRoomPlanning fMealRoomPlanning = new MealRoomPlanning(true))
        {
            fMealRoomPlanning.MdiParent = this;
            fMealRoomPlanning.Show();
        }
    }

这就是为什么许多样式检查建议使用this-Qualifier,尽管它是多余的。如果您设置了本地、全局或类变量,这会更清楚。

【讨论】:

  • 是的,我还认为 OP 将 using 与 VB 中的 With 关键字混淆了。
  • 我试过了也不管用。窗口打开和关闭就好像 Dispose() 直接出现在 Show() 之后。使用 ShowDialog() 它可以工作,但就像一个模态窗口。
  • 这正是 using-block 应该做的 - 在块完成执行后处理使用的对象。如果您不想要这种行为,请不要使用 using-block。
【解决方案2】:

我终于明白了,非模态表单不需要使用。

当一个非模态表单关闭时,WinForms会自动调用Dispose。

与使用 ShowDialog 打开的表单不同,不会自动调用 Dispose。

【讨论】:

    【解决方案3】:

    尝试将MdiParent = this 更改为fMealRoomPlanning.MdiParent = this

    【讨论】:

      【解决方案4】:

      尝试更改第二个代码,在为 MealRoomPlanning 类创建 object 之后 将 MdiParent = this; 更改为 fMealRoomPlanning.MdiParent = this;

      private void RoomMealHistory_Click(object sender, EventArgs e)
      {
          using (MealRoomPlanning fMealRoomPlanning = new MealRoomPlanning(true))
          {
              fMealRoomPlanning.MdiParent = this;
              fMealRoomPlanning.Show();
          }
      }
      

      【讨论】:

      • 这个答案与Computerfreak 的答案有何不同?除此之外,它缺少@Computerfreak 提供的解释
      • @MongZhu,如果你看回复时间你会注意到CompufreakNaveen Doggamy答案之间的时间差相当小。我们发布了我们的答案,却不知道答案已经给出。
      • @catman0745 看看timeline 这个答案比你和 Compufreak 的答案晚了 20 分钟。我看着它出现在这里。否则我不会写我的评论。 20 分钟应该足以看到已经发布的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-31
      • 2016-06-05
      • 2010-10-25
      • 2011-10-10
      • 2018-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多