扩展通用List<>的方法类型

时间:2018-05-01 00:46:03

标签: c# .net extension-methods

TL; DL:简化method<returnType, ListType>(this List<ListType>, ...)method<returnType>(this List<anyType>, ...)的通用列表

我正在寻找一个扩展方法,它允许我在(任何类型的对象)的List中获取所有属性“P”的值

到目前为止,我已经使用了这种方法:

public static T[] selectAll<T, U>(this List<U> list, string property)
{
    List<T> r = new List<T>();          // prepare a list of values of the desired type to be returned
    foreach(object o in list)
    {
        Type mt = o.GetType();          // what are we actually dealing with here? (List of what?)   <-- This should be the same as Type U
        IList<PropertyInfo> props = new List<PropertyInfo>(mt.GetProperties());          // Get all properties within that type
        foreach(PropertyInfo p in props)
        {
            if (p.Name == property)                   // Are we looking for this property?
                r.Add((T)p.GetValue(o, null));        // then add it to the list to be returned
        }
    }
    return r.ToArray();
}

因为你不能简单地拥有一个未知的返回类型,我知道有必要在方法调用中指出返回类型,例如:

List<Control> SomeListOfControls = ...

string[] s = SomeListOfControls.selectAll<字符串 , Control>("Text");

但是,由于该列表中项目的类型与此方法无关,我想从等式中消除Type变量。 我希望我可以简单地致电

List<Control> SomeListOfControls = ...

string[] s = SomeListOfControls.selectAll<string>("Text");&lt; - 你知道这个List包含的是&gt;。&lt;

例如。

但我想不出办法做到这一点。 即使在编译之前,我也可以看到

public static T[] selectAll<T>(this List<> list, string property)

Unexpected use of an unbound generic name(意为List<>)。

List<object>未能注册为各类List<?extends object>的扩展名,可以这么说。

如果可能的话,我可以如何做到这一点?

PS:似乎可能存在“原生”方式(通常是.net或甚至是C#)来检索&lt; T&gt;的集合了。 P来自可能具有类型T的属性P的集合 - 我无法使用select和所有...来解决它...但如果有:我很乐意了解它:)

2 个答案:

答案 0 :(得分:1)

看起来您正在寻找参数的非通用版本 - pointer_ew = pointer+5IList可以使用

IEnumerable

答案 1 :(得分:0)

后果(哪里出了问题)

虽然我已导入(using

System.Collections.Generic

System.Collections.Specialized

我不知道那些名称空间部分继承的类实际上是System.Collections。我以为我得到了两半蛋糕,而我却在错过地壳时得到了两个馅料。

因此,当我尝试使用IEnumerable时,例如,如果没有Type指示符,我亲爱的IDE(Visual Studio 2017)就不会接受它。

对于任何通过谷歌来到这里遇到同样问题的人:

同时使用.Generic.Specialized将无法涵盖, 集合类型的大部分内容都来自父System.Collections

public static T[] selectAll<T>(this IList list, string property){
    ...
}

public static T[] selectAll<T>(this IEnnumerable list, string property){
    ...
}

可能会为你服务。

虽然,对于我上面概述的情况,

public static T[] selectAll<T>(this IEnumerable<object> list, string property){
    ...
}

工作得很好(而IList<object>未能注册为List<的扩展名?>

空间和概念的命名可能会产生误导:

我认为IList<Type>是专门的(按类型),IList泛型(因为它适用于所有<Type> s) - 但在C#世界中,它是另一种方式:IList本身被认为是“非泛型的” - 通用的问题是从外部接近(如何在上下文中处理)而不是内部(它包含什么(或可以)) ) - 像我这样的高级程序员可能会直觉出错。

总结:

  • System.Collections包含的不仅仅是其类的总和

  • 直观的通用集合被称为非泛型集合,因为可以这么说的低级权力

  • System.Collections.IEnumerable似乎适用于所有类型的列表

  • 阅读官方文档通常很有用。 (等等......一般还是具体?哦,谁知道了?P)