C# &引用;是"-引用或gettype()

C# &引用;是"-引用或gettype(),c#,.net,winforms,comparison,C#,.net,Winforms,Comparison,我在WinForms表单中搜索一些控件,借助于foreach语句。 我正在比较通过“is”引用找到的对象(a is DataGridView)。“a”是控件集合中的对象。 到目前为止效果很好,因为在我的表单上比较的对象彼此都有足够的不同 在我创建的一个新表单中,我使用了一个名为myu-DataGridView的DataGridView的派生版本。因此,当通过“is”-引用将my_datagridview与datagridview进行比较时,不会引发异常,这是“错误的”,因为我希望将两者分开处理

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

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

有没有办法正确比较
my_datagridview
datagridview

有没有办法正确比较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
派生的任何其他类,您希望发生什么情况。首先从最具体的类开始。因此:

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

.

首先比较派生程度较高的版本并执行其操作,然后比较派生程度较低的类型(假设操作是互斥的)

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

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

首先我更喜欢

所以


上行总是成功,下行总是失败

因此,当您将my_datagridview上传到datagridview时,它将始终成功

当向下广播失败时,执行此操作将导致InvalidCastException

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

if(m_dgv==null)
{
//its a datagridview
}
else
{
//its a mydatagridview
}
为了避免抛出上述异常,可以使用as操作符

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

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

if(m_dgv==null)
{
//its a datagridview
}
else
{
//its a mydatagridview
}

根据我们上面的评论,我认为没有必要找到控件。例如,如果表单上有一个按钮,通过单击grid1发生了什么,您可以在该按钮的单击事件处理程序中使用以下内容:

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

谢谢你保护我们的理智。谢谢你的快速回答。我没有任何其他派生类,也不打算包含/创建其他派生类。既然已经知道网格应该以何种方式运行,为什么还需要遍历控件?只是好奇。@danish:因为它为我节省了很多代码。所有
datagridview
都包含在多个
groupbox
(至少2层)中,我正好有8个(
datagridview
)。这样更简洁。我还是不明白找到控件的必要性。如果屏幕上的用户操作X应该导致网格Z中的操作Y,为什么不捕获操作X并在网格上执行操作?@danish:因为我不是在处理特定的
DataGridView
中的事件,而是由其他元素触发的事件,而这反过来需要更新
DataGridView
(但不是所有的,只是具体的)。没有“需要”,只是用这种方式缩短。缩短并不总是有效的。