泛型 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
和所有......但如果有:我很乐意了解它 :)
看起来您正在寻找参数的非通用版本 - IList
或 IEnumerable
都可以
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)
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#)来检索 select
和所有......但如果有:我很乐意了解它 :)
看起来您正在寻找参数的非通用版本 - IList
或 IEnumerable
都可以
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)