简体   繁体   中英

How to make an extension method on interface available on all implementing classes?

I have a class Triangle and I added an extension method to the type List<Triangle> as shown below. It works just as one would expect.

public static string Export(this List<Triangle> self) { ... }

However, I also have other classes, like Rectangle and Trapezoid , which would need each own Export function, like this.

public static string Export(this List<Rectangle> self) { ... }
public static string Export(this List<Trapezoid> self) { ... }

Since the code in it the method is exactly the same and will remain so for any new kind of figure, I figured out (get it? figured out) that it's suitable to go for an interface. So, the classes are now implementing IFigure , which allowed me to consolidate the code in the extensions as shown below.

    public static string Export(this List<IFigure> self) { ... }

The only problem is that now the code doesn't compile because the lists of specific implementations doesn't know about the extension method. I'll have to change all the methods that return the type eg List to returning type List<IFigure> and it seems like a lot of work. Besides that, I fear that I then will need to convert those lists to the actual implmented classes for all the operations except the exporting.

Is it possible to have an extension method on interface type so that it covers all the implementing classes?

IEnumerable <>的扩展方法将起作用

public static string Export(this IEnumerable<IFigure> self) { ... }

You can use generics to make it resolve:

public static string Export<TFigure>(this List<TFigure> self)
    where TFigure : IFigure
{ ... }

Inside the method you will have all of the properties/methods of IFigure on the elements inside the self list.

It'll work for a list of IFigure itself or any inherited types

new List<IFigure>().Export();
new List<Triangle>().Export();

The TFigure is just the name of the generic declaration (it could be anything or just T to keep it simple). The where TFigure : IFigure will tell the compiler that it should only accept a type that implements IFigure. This is called a generic constraint.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM