4

我想获取 BindingSource 连接或配置的项目的类型。BindingSource.DataSource 属性可以设置为对象、列表或类型。如果是Type,显然还没有绑定项,但我还是想得到Type。对于列表,我需要项目类型,而不是列表类型。

我目前有一个用于实现 IListItemType 接口的业务对象的自定义列表类型,我创建它是为了解决这个问题。我现在想让它以更通用的方式工作,以便它适用于任何列表。

我已经查看了 API 文档,寻找一种很好的方法来做到这一点,但到目前为止我还没有运气。我错过了什么,或者这只是我不能或不应该做的事情?

4

3 回答 3

8

我最近在框架中遇到了ListBindingHelper类,其中包含我正在寻找的一切:

System.Windows.Forms.ListBindingHelper.GetListItemType()

返回列表或集合中包含的项目的类型。

ListBindingHelper.GetListItemProperties()

返回描述列表中包含的项目的属性的 PropertyDescriptorCollection。

于 2010-07-13T22:21:33.513 回答
2

没有完全通用的方法来获取列表的“类型”。最常见的方法是检查第一项,但这可能会产生误导,因为您可以在不太具体的集合中拥有更具体类型的对象换句话说,集合可能是 a ,但第一项可能是 a ,导致您猜测它是 a )。如果您确信所有元素都是同一类型(意味着没有比集合的泛型类型或任何其他对象更具体),那么检查第一项是最简单的。List<object>stringList<string>

除此之外,您可以使用检查列表的实际类型GetType并检查其接口。有可能任何强类型集合都将实现IEnumerable<T>,因此您可以遍历其接口以查找IEnumerable其泛型,然后查看其泛型类型参数。它(不仅仅是)有点做作,但它应该可以工作。

TL;DR 版本

试试这个。假设您使用的是 .NET 3.5 并将列表存储在一个名为的变量中list

var listType = list.GetType().GetInterfaces()
              .Where(t => t.Name == "IEnumerable" && t.IsGenericType)
              .Select(t => t.GetGenericArguments()[0]).FirstOrDefault();

只要清单执行IEnumerable<T>,这会给你T。如果没有,那么列表类型很可能是object无论如何。

于 2010-06-14T19:16:05.887 回答
1

自从这个答案出现以来已经有一段时间了,但以防万一有人还在寻找答案......

我遇到了类似的问题。我的场景是 BindingSource.DataSource 将始终绑定到 IEnumerable 但列表中可能没有任何项目。事实证明,BindingSource 有一个名为“itemType”的私有实例成员。此字段正是您要查找的内容:如果 BindingSource 绑定到列表,则显示列表的元素类型;如果没有列表,则显示 BindingSource 绑定到的对象的类型。

为了访问字段值,我使用了一些 hacky 反射:

FieldInfo fi = 
    typeof(BindingSource)
    .GetField("itemType", BindingFlags.NonPublic | BindingFlags.Instance);
Type myElementType = fi.GetValue(DataBinder.RestrictedDataBinding) as Type;

没有做太多研究,我有点假设它正在做的是显示 innerList 的元素类型,这就是为什么 DataSource 是否是列表类型并不重要。此外,我假设此字段将准确显示 BindingSource 支持的任何类型列表的元素类型(包括 IQueryables 等)。

警告:我没有对这个字段进行太多测试,所以我不知道是否存在使其无法读取正确元素类型的情况。例如,重置 BindingSource 的 DataSource 属性时,字段是否总是准确更新?如果将 DataSource 属性重置为具有不同 elementType 的列表怎么办?就我而言,这些例外和其他例外不适用,但您可能想测试它们。

最后,使用反射侵入私有字段会破坏各种 oop 原则。记住这一点。另外,请记住,itemType 字段被隐藏很可能是有充分理由的。如果您需要进一步调查,BindingSource 类的代码是公开的。

于 2014-10-13T18:34:39.120 回答