如何编写泛型类扩展运算符 [英] How to code generic class extension operator

查看:125
本文介绍了如何编写泛型类扩展运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写扩展转换运算符

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 type T1 to the type T2. Your type constraints for T1 and T2 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 and T2:

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 to T2 add then to the target collection, one by one, in a loop. I replaced Collection with List just for example, because Collection is probably some your type which I don't have.

By the way, it is not quite clear why did you call your class CollectionExtension :-).
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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆