2

有什么区别或有什么区别:

myDgv.SelectedRows.Count 

对比

myDgv.Rows.GetRowCount(DataGridViewElementStates.Selected)

在 DataGridView 的上下文中,Windows 窗体?

4

2 回答 2

2

我认为在您在这里提到的特定情况下,除了处理 DataGridView 数据的顺序之外,这两个选项之间几乎没有区别。如果您要保存用于从中获取 Count 的中间对象,您可能会担心 SelectedRows 在进行引用时会向您呈现静态快照,但由于这两个选项都直接调用另一个方法这真的不是一个因素。

每当您对如何挖掘此类内容感到非常好奇时,您可以打开 ILDASM 并浏览您的 GAC 以查看调用的实际工作方式。

从某种程度上来说,使用 SelectedRows 和 Rows.GetCount() 之间的区别在于,我们要么获取过滤的集合并检查其大小,要么获取整个集合并将其过滤到我们然后检索其大小的子集。这几乎是由我们最初使用的 IL 向我们展示的内容所证明的。

.method public hidebysig static void  testDG() cil managed
{
  // Code size       34 (0x22)
  .maxstack  2
  .locals init ([0] class [System.Windows.Forms]System.Windows.Forms.DataGridView dgvTest,
           [1] int32 myNum,
           [2] int32 otherum)
  IL_0000:  nop
  IL_0001:  newobj     instance void [System.Windows.Forms]System.Windows.Forms.DataGridView::.ctor()
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  callvirt   instance class [System.Windows.Forms]System.Windows.Forms.DataGridViewSelectedRowCollection [System.Windows.Forms]System.Windows.Forms.DataGridView::get_SelectedRows()
  IL_000d:  callvirt   instance int32 [System.Windows.Forms]System.Windows.Forms.BaseCollection::get_Count()
  IL_0012:  stloc.1
  IL_0013:  ldloc.0
  IL_0014:  callvirt   instance class [System.Windows.Forms]System.Windows.Forms.DataGridViewRowCollection [System.Windows.Forms]System.Windows.Forms.DataGridView::get_Rows()
  IL_0019:  ldc.i4.s   32
  IL_001b:  callvirt   instance int32 [System.Windows.Forms]System.Windows.Forms.DataGridViewRowCollection::GetRowCount(valuetype [System.Windows.Forms]System.Windows.Forms.DataGridViewElementStates)
  IL_0020:  stloc.2
  IL_0021:  ret
} // end of method Program::testDG

正如您可能怀疑的那样,尽管这种方式引出了这两个较低级别调用的作用的问题。

在这种情况下,DataGridView 上的 Rows 属性创建 DataGridViewsRowCollection 的一个实例并将其传回,因为它映射到 get_Rows。

.method public hidebysig specialname instance class System.Windows.Forms.DataGridViewRowCollection 
        get_Rows() cil managed
{
  // Code size       27 (0x1b)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldfld      class System.Windows.Forms.DataGridViewRowCollection System.Windows.Forms.DataGridView::dataGridViewRows
  IL_0006:  brtrue.s   IL_0014
  IL_0008:  ldarg.0
  IL_0009:  ldarg.0
  IL_000a:  callvirt   instance class System.Windows.Forms.DataGridViewRowCollection System.Windows.Forms.DataGridView::CreateRowsInstance()
  IL_000f:  stfld      class System.Windows.Forms.DataGridViewRowCollection System.Windows.Forms.DataGridView::dataGridViewRows
  IL_0014:  ldarg.0
  IL_0015:  ldfld      class System.Windows.Forms.DataGridViewRowCollection System.Windows.Forms.DataGridView::dataGridViewRows
  IL_001a:  ret
} // end of method DataGridView::get_Rows

当我们查看 DataGridView 上的 SelectedRows 属性时,我们发现它最初所做的不仅仅是返回一个集合,但在主 try 块中,我们再次看到我们的“get_Rows”调用 (IL_0045)。

.try
  {
    IL_0035:  br.s       IL_0056
    IL_0037:  ldloc.3
    IL_0038:  callvirt   instance object [mscorlib]System.Collections.IEnumerator::get_Current()
    IL_003d:  unbox.any  [mscorlib]System.Int32
    IL_0042:  stloc.1
    IL_0043:  ldloc.0
    IL_0044:  ldarg.0
    IL_0045:  call       instance class System.Windows.Forms.DataGridViewRowCollection System.Windows.Forms.DataGridView::get_Rows()
    IL_004a:  ldloc.1
    IL_004b:  callvirt   instance class System.Windows.Forms.DataGridViewRow System.Windows.Forms.DataGridViewRowCollection::get_Item(int32)
    IL_0050:  callvirt   instance int32 System.Windows.Forms.DataGridViewSelectedRowCollection::Add(class System.Windows.Forms.DataGridViewRow)
    IL_0055:  pop
    IL_0056:  ldloc.3
    IL_0057:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
    IL_005c:  brtrue.s   IL_0037
    IL_005e:  leave.s    IL_0074
  }  // end .try

这表明我们正在为我们的两个选择执行相同的检索和过滤操作,并且可以合理地预期执行它们的“成本”是相同的。

如果您注意到这些调用的性能问题,您可以运行一些测试以查看是否存在差异,但基于 IL,如果您发现两个调用之间有任何明显区别,我会感到惊讶

于 2012-09-18T04:53:34.600 回答
1

Microsoft建议SelectedCells在较小程度SelectedRows上对于大型数据集效率低下,您应该使用GetCellCount/GetRowCount代替。

于 2013-06-28T10:29:17.997 回答