【问题标题】:Casting a C# List<>强制转换 C# 列表<>
【发布时间】:2011-03-16 11:36:59
【问题描述】:

我有一个看似简单的问题,但我似乎找不到答案。我有一个带有属性的类。这些属性之一返回一个列表。我有一个方法可以循环遍历任何类的所有属性并为该类(通信日志应用程序)生成一个 TreeNode。当我遇到标识为 List 的属性时,我不知道如何正确转换 property.GetValue。 property.PropertyType 是已知的,但无论我尝试什么,都会出现编译错误或运行时错误。

这就是我想要做的......

foreach (PropertyInfo prop in props)
{
    if(prop.PropertyType.Namespace == "System.Collections.Generic")
    {
        List<object> oList = prop.GetValue(data, null);
        MessageBox.Show(oList.Count.ToString())
    }
}

如果我在 GetValue 行设置断点,prop 参数就知道它是一个包含三个元素的“myclass”项目列表。我只是不能将它转换为对象列表(这很好)或将其转换为实际的“myclass”元素列表,这会更好。如何将 PropertyInfo.GetValue(一个对象)的返回值转换为它的 List?

【问题讨论】:

标签: reflection c#-3.0


【解决方案1】:

首先,检查命名空间是不够的(或者在这种情况下根本不需要)。你可以检查 prop.PropertyType 是否是ICollection 的一个实例(你可以使用IsAssignableFrom)。我建议使用 ICollection,因为您似乎只关心伯爵。

然后您可以将其转换为 ICollection(非泛型)并运行 Enumerable.Cast,例如:

IEnumerable<MyClass> res = ((ICollection)prop.GetValue(data,null)).Cast<MyClass>();
MessageBox.Show(res.Count().ToString());

与直接转换为 List 相比的优势在于它适用于任何集合。但是,如果您不需要,可以尝试其他答案的建议。

【讨论】:

  • 你就是男人(当然不分性别)!!! IEnumerable 是我需要的。由于递归函数采用对象而不是特定的类类型,因此我可以摆脱强制转换为对象列表。这完美地工作。非常感谢。至于 IsAssignableFrom.... 我该如何使用它?
  • 试试 if (ICollection.IsAssignableFrom(prop.PropertyType)) { ... }
【解决方案2】:

你试过了吗

prop.GetValue(data, null) as List<YourClass>;

【讨论】:

  • 问题的核心是“YourClass”会随着我尝试记录的每个不同对象而变化。该属性知道它是什么类型的列表,但我不能在 中放入任何程序化的东西。如果这样做,我会收到编译器错误。我对其他答案也有这个问题。如果我想通过检查属性的类型来做到这一点,那将是可行的方法,但我似乎无法找到可以在 中放入的内容。
【解决方案3】:

我猜你想要逆变。

你想这样做吗?

List<object> list = (List<Product>)object;

List&lt;object&gt;List&lt;Product&gt; 不会被视为同一类型。

C# 4.0 为接口和委托泛型参数引入了协变和逆变,但无论如何,IList&lt;T&gt; 没有逆变。

在我看来,我认为您需要重新考虑您的对象图!

PD:如果您需要这方面的指导,请发表评论!

【讨论】:

    猜你喜欢
    • 2020-02-23
    • 2012-08-05
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多