如何编写泛型类扩展运算符 [英] How to code generic class extension operator
问题描述
我正在尝试编写扩展转换运算符
System.Collections.Generic.Collection。
目的是转换T1类型集合到T2类型的集合。
我已经定义了从T1到T2的所需转换集。
< pre lang =xml> public static class CollectionExtension
{
public static explicit operator Collection < T2 > (此Collection < T1 > rhs)
其中T1:class
其中T2:class,new()
{
集合< T2 > lhs = new Collection < T2 > ();
// Foreach ...
返回lhs;
}
}
我通过查看现有帖子得到了这一点,但它不会编译。
有人可以解释一下如何做这件事。
谢谢。
这个想法很简单:你应该再提供一个参数(方法参数,而不是泛型参数):委托实例将类型T1
的元素转换为类型T2
。T1
和T2
的类型约束绝对是多余的,没用。您可以使用任何类型的元素,而不仅仅是类。
您的委托类型参数本身应该是通用的,使用相同的通用参数,T1
和T2
:
public static class SomeExtensionUtility {
public static 列表< T2>转换列表< T1,T2>(
此列表< T1>列表,
System.Func< T1,T2>转换器){
返回 // 请自行实施
}
}
实现很简单:将源集合中的元素转换为T2
然后在循环中逐个添加到目标集合。我将Collection
替换为List
,例如,因为Collection
可能是你的类型,我没有。
顺便说一下,为什么你打电话给你的班级不太清楚CollectionExtension
:-)。
它不会以这种方式工作,因为运算符作为静态类的运算符将无法编译。但是我的班级可以用作扩展班。
这个用法扩展方法与其他扩展方法不同:
使用 MyExtensionMethods; // 我们假设这是具有SomeExtensionUtility的命名空间
// 让我留下System.Collections.Generic.List<>,例如,
// 它将更容易演示:
使用 System.Collections.Generic;
// ...
List< ;串GT; stringList = new List< string>();
List< int> intList = stringList.ConvertList< string,int>(
(stringValue)= > { return int .Parse(stringValue);}
);
对于某些背景,请阅读:
http://en.wikipedia。 org / wiki / Covariance_and_contravariance_%28computer_science%29 [ ^ ],
http: //msdn.microsoft.com/en-us/library/dd799517%28v=vs.110%29.aspx [ ^ ]。
此协方差/逆变问题实际上是非平凡的,但问题m和我演示的解决方案都是微不足道的。
-SA
我认为谢尔盖 首先到达那里,并为您提供所需的关键洞察力;我建议你接受他的答案。
虽然我不熟悉ObjectModel.Collection类,但我编写了一个扩展方法来将一个Type的Generic List转换为另一种类型的通用列表:public static class GenericListExtensions
{
public static 列表与LT; T2> ConvertGenericList< T1,T2>(此列表< T1> T1List,Func< T1,T2> conversionFunc)
{
return T1List.Select(conversionFunc).ToList();
}
}用法示例:
List< int> intList = new 列表< int> { 1 , 2 , 3 , 4 , 5 };
List< string> stringList = intList.ConvertGenericList< int,string>(anInt = > anInt.ToString());Linq和Lambda真的允许一些有用的简洁!
I am trying to code an extension conversion operator for
System.Collections.Generic.Collection.
The purpose is to convert a collection of T1 types to a collection of T2 types.
I already defined the required set of conversions from T1 to T2.
public static class CollectionExtension
{
public static explicit operator Collection<T2>(this Collection<T1> rhs)
where T1 : class
where T2 : class, new()
{
Collection<T2> lhs = new Collection<T2>();
// Foreach ...
return lhs;
}
}
I got as far as this by looking at existing posts, but it won't compile.
Could some one please explain how to do this.
Thanks.
The idea is simple: you should provide one more parameter (method parameter, not generic parameter): the delegate instance converting the element of the typeT1
to the typeT2
. Your type constraints forT1
andT2
are absolutely redundant and useless. You can work with elements of any types, not just classes.
Your delegate-type parameter should itself be generic, using the same generic parameters,T1
andT2
:
public static class SomeExtensionUtility { public static List<T2> ConvertList<T1, T2>( this List<T1> list, System.Func<T1, T2> convertor) { return // please implement it yourself } }
The implementation is simple: you convert elements in source collection toT2
add then to the target collection, one by one, in a loop. I replacedCollection
withList
just for example, becauseCollection
is probably some your type which I don't have.
By the way, it is not quite clear why did you call your classCollectionExtension
:-).
It won't work this way, because you operator, as the operator of the static class, won't compile. But my class can be used as the extension class.
[EDIT]
The usage of this extension method won't be different from any other extension method:
using MyExtensionMethods; // let's assume this is the namespace with SomeExtensionUtility // let me stay with System.Collections.Generic.List<>, just for example, // it will be easier to demonstrate: using System.Collections.Generic; //... List<string> stringList = new List<string>(); List<int> intList = stringList.ConvertList<string, int>( (stringValue) => { return int.Parse(stringValue); } );
For some background, please also read:
http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29[^],
http://msdn.microsoft.com/en-us/library/dd799517%28v=vs.110%29.aspx[^].
This covariance/contravariance matter is really non-trivial, but the problem and the solution I demonstrated are trivial enough.
—SA
I think Sergey "got there" first, and gave you the key insight you need; I suggest you accept his answer.
While I am not familiar with the ObjectModel.Collection class, I have written an extension method to convert a Generic List of one Type to a Generic List of another Type:public static class GenericListExtensions { public static List<T2> ConvertGenericList<T1, T2>(this List<T1> T1List, Func<T1,T2> conversionFunc) { return T1List.Select(conversionFunc).ToList(); } }An example of usage:
List<int> intList = new List<int>{1,2,3,4,5}; List<string> stringList = intList.ConvertGenericList<int, string>(anInt => anInt.ToString());Linq and Lambda really allow some useful brevity !
这篇关于如何编写泛型类扩展运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!