繁体   English   中英

如何获得旧式收藏中物品的类型?

[英]How do I get the type of the item in an old style collection?

我实际上想做的是编写一个函数,该函数允许我在DataGridView中更改选择,并且我想编写一个函数并将其用于行和列。 这是一个简单的示例,该示例取消选择所有内容并选择新的行或列:

private void SelectNew<T>(T collection, int index) where T : IList
{
  ClearSelection();
  collection[index].Selected = true;
}

我的问题是,这不起作用,因为无法推导出.Selected()可用,因为这是非通用的IList。

运用

where T : IList<DataGridViewBand>

会很好,但是由于DataGridViewRowCollection(和-Column-)仅从IList派生,所以这是行不通的。

在C ++中,我可能会使用特征习语。 有没有办法在C#中做到这一点,还是有一种更惯用的方式?

从理论上讲,可以使用反射来完成此操作; 因为您的明确目标只是处理行或列,所以最简单的选择就是为该函数创建两个重载:

private void SelectNew(DataGridViewColumnCollection collection, int index)
{
    ClearSelection();
    collection[index].Selected = true;
}

private void SelectNew(DataGridViewRowCollection collection, int index)
{
    ClearSelection();
    collection[index].Selected = true;
}

如果您尝试使用反射来做到这一点,那么它会起作用,但是它会更慢,更易读,并且有没有编译时间保护的危险; 人们将能够传递其他类型的不具有Selected属性的列表,并且这些列表会在运行时失败。

一种可能是使用dynamic

private void SelectNew(IList collection, int index)
{
  ClearSelection();
  ((dynamic)collection)[index].Selected = true;
}

要么:

private void SelectNew(IList collection, int index)
{
  ClearSelection();
  DataGridViewBand toSelect = ((dynamic)collection)[index];
  toSelect.Selected = true;
}

这样做的最大缺点是,您将失去编译时类型的安全性,因此,除非它阻止了大量的代码重复,否则我不建议这样做。

(第二个版本具有更多的编译时类型安全性,但代价是更加冗长和显式。)

如果您有一个实现IEnumerable的集合,并且提前知道它包含什么类型的元素,则可以执行以下操作:

IList<DataGridViewBand> typedCollection = collection
                                          .Cast<DataGridViewBand>()
                                          .ToList();

这将允许您调用通用扩展方法:

private void SelectNew<T>(T collection, int index)
   where T : IList<DataGridViewBand>
{
  ClearSelection();
  collection[index].Selected = true;
}

typedCollection.SelectNew(1);

编辑:

如果您决定要在IList<DataGridViewBand>上限制T,则最好直接为该类型编写一个方法,因为使用泛型不会获得任何好处。

IList<DataGridViewBand> typedCollection = collection
                                          .Cast<DataGridViewBand>()
                                          .ToList();

private void SelectNew(IList<DataGridViewBand> collection, int index)
{
  ClearSelection();
  collection[index].Selected = true;
}

typedCollection.SelectNew(1);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM