泛型 List<> 类型的扩展方法

Extend method for generic List<> types

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

我正在寻找一个扩展方法,允许我获取(任何类型的对象)

列表中所有属性 "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();
}

因为你不能简单地拥有一个未知的 return 类型,我理解有必要在方法调用中指明 return 类型,例如:

List<Control> SomeListOfControls = ...

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

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

List<Control> SomeListOfControls = ...

string[] s = SomeListOfControls.selectAll<string>("Text"); <-- 你他妈的很清楚这个列表由什么组成 >.<

例如。

但我想不出办法来做到这一点。 甚至在编译之前我就可以看到

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

是一个Unexpected use of an unbound generic name(意思是List<>)。

并且List<object>无法注册为各种List<?extends object>的扩展,可以这么说。

如果可能的话,我怎样才能完成这项工作?

PS: 似乎有一种 "native" 方法(.net 甚至一般的 C#)来检索 P 来自可能具有类型 T 的属性 P 的集合 - 我无法使用 select 和所有......但如果有:我很乐意了解它 :)

看起来您正在寻找参数的非通用版本 - IListIEnumerable 都可以

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

后果(哪里出了问题)

虽然我已经导入了 (using)

System.Collections.Generic

System.Collections.Specialized,

我不知道 类 这些名称空间部分继承自 System.Collections。我以为我得到了两半的蛋糕,而我却得到了两个馅料却没有蛋糕皮。

因此,当我尝试使用 IEnumerable 时,例如,我亲爱且值得信赖的 IDE(Visual Studio 2017)不会接受没有类型指示符的它。

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

同时使用 .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>)——但在 C# 世界中,它是另一个解决方法: IList 本身被认为是 "non-generic" - 通用性问题是从外部(在上下文中如何处理)而不是内部(做什么(或可以)它包含)-像我这样的高级程序员可能会凭直觉犯错。

总结:

  • System.Collections 的总和大于其 类

  • 直观上,泛型集合被称为非泛型,因为这样说的较低级别的权力

  • System.Collections.IEnumerable似乎适用于各种List

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