【问题标题】:"is"-reference or gettype()“是”-reference 或 gettype()
【发布时间】:2012-07-25 15:47:32
【问题描述】:

我在 foreach 语句的帮助下在我的 WinForms 表单中搜索了一些 controls。 我正在比较通过“is”引用 (a is DataGridView) 找到的对象。 “a”是控件集合中的对象。 到目前为止效果很好,因为我表单上的比较对象都彼此完全不同。

在我创建的一个新表单中,我使用了一个名为my_datagridviewDataGridView 的派生版本。因此,当通过“is”引用将my_datagridviewDataGridView 进行比较时,不会引发异常,这是“错误”的,因为我想分别处理这两个。

有没有办法正确比较my_datagridviewDataGridView

【问题讨论】:

  • 既然你已经知道哪个网格应该以什么方式循环,为什么还需要循环访问控件?只是好奇。
  • @danish:因为它为我节省了很多代码。所有DataGridViews 都包含在多个GroupBoxes(至少2 层)中,而我正好有8 个(DataGridViews)。这种方式更简洁。
  • 我仍然无法理解需要找到控件。如果用户在屏幕上的操作 X 应该导致网格 Z 中的操作 Y,为什么不捕获操作 X 并在网格上执行操作?
  • @danish:因为我不是在处理特定 DataGridView 中的事件,而是由其他元素触发的事件,作为回报需要更新 DataGridViews(但不是全部它们,只是特定的)。

标签: c# .net winforms comparison


【解决方案1】:

有没有办法正确比较 my_datagridview 和 DataGridView?

一种选择是使用类似的东西:

if (a is MyDataGridView) // Type name changed to protect reader sanity
{
}
else if (a is DataGridView)
{
    // This will include any subclass of DataGridView *other than*
    // MyDataGridView
} 

当然,您可以使用GetType() 来完全匹配。重要的问题是您希望从DataGridView 甚至MyDataGridView 派生的任何其他 类发生什么。

【讨论】:

  • 感谢您保护我们的理智。
  • 感谢您的快速回答。我没有任何其他派生类,也不打算包含/创建其他类。
【解决方案2】:

是的。首先从最具体的课程开始。所以:

if (a is my_datagridview)
{
    //....
}
else if (a is DataGridView)
{
    // ....
}

See MDSN here.

【讨论】:

    【解决方案3】:

    首先我喜欢更好

    所以

    var dg = a as DataGrindView
    var mygd = a as MyDataGridView
    
    if(mygd != null) {...}
    else
    {
       if(dg != null) {...}
    }
    

    【讨论】:

      【解决方案4】:

      向上转型总是成功,向下转型总是失败!

      因此,当您将 my_datagridview 向上转换为 DataGridView 时,它总是会成功!

      这样做会导致 InvalidCastException,因为向下转换失败!

      DataGridView dgv = new DataGridView();
      myDataGrivView m_dgv = (myDataGridView)dgv;
      

      为避免抛出上述异常,可以使用as操作符!

      如果向下转换失败,它不会抛出异常,而是返回 null!

      DataGridView dgv = new DataGridView();
      myDataGrivView m_dgv =dgv as myDataGridView;
      
      if(m_dgv==null)
      {
      //its a datagridview
      }
      else
      {
      //its a mydatagridview
      }
      

      【讨论】:

        【解决方案5】:

        先比较派生较多的版本并执行其动作,再比较派生较少的类型(假设动作是互斥的)

        或者,将两个比较放在一个条件语句中:

        if ((a is my_datagridview) && (!a is DataGridView))
        {
          // This will only match your derived version and not the Framework version
        }
        // The else is needed if you need to do something else for the framework version.
        else if (a is DataGridView)
        {
          // This will only match the framework DataGridView because you've already handled
          // your derived version.
        }
        

        【讨论】:

          【解决方案6】:

          根据我们上面的 cmets,我认为不需要找到控件。例如,如果您在表单上有一个按钮,并且通过单击 grid1 应该发生的事情,您可以在按钮的单击事件处理程序中使用它:

          private void ClickButtonOne(object sender, EventArgs e)
          {
          // Do something with datagridview here
          }
          

          【讨论】:

          • 没有“需要”,只是这样更短。
          • 较短并不总是有效的。
          猜你喜欢
          • 2010-11-02
          • 1970-01-01
          • 2012-03-04
          • 1970-01-01
          • 1970-01-01
          • 2012-07-03
          • 1970-01-01
          • 2012-04-29
          相关资源
          最近更新 更多