Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a variable number of generic type parameters

to be specific, I want to write an export function which I can use like this:

List<HistoryBook> HistoryBooks = something;
List<MathBook> MathBooks = something;
List<ScienceBook> ScienceBooks = something;

ExcelExporter.Export(FileName, HistoryBooks, MathBooks, ScienceBooks);

I thought about something like the code below, but in this case I have to cast everything to a "List of object" which is not what I want.

public void Export(string FileName, params List<object>[] Data)

Can you give me a hint how to solve this elegantly?

like image 851
Jens Avatar asked Jan 17 '23 00:01

Jens


2 Answers

If, as you say, you want to be able to pass completely unrelated lists, maybe you should accept the base IList interface:

public void Export(string FileName, params IList[] Data)

All List<T> objects implement IList, as well as the generic IList<T>, so you can enforce that.

Actually, depending on what you need to do with these lists in the Exporter, perhaps enforcing IEnumerable is enough for you, if all you need is forward-only read-once functionality.

Best way to decide is to determine what the shared functionality you need for all parameters, and define your method signature to enforce that functionality.

UPDATE

Based on your comment, it seems what you want is possible in C# 4.0 using covariant/contravariant generics, meaning that a generic ISomething<out object> could receive an ISomething<string>. The problem is that IList<T> doesn't define a covariant generic parameter, so passing IList<string> for IList<object> doesn't work.

However, IList<T> inherits IEnumerable<out T>, which DOES define a covariant parameter. So if your Export method receives a params IEnumerable<object>[] data parameter, you SHOULD be able to pass it any IList<T> you want.

like image 183
Avner Shahar-Kashtan Avatar answered Jan 21 '23 16:01

Avner Shahar-Kashtan


class Book {}

class ScienceBook : Book {}

class MathBook : Book  {}

class ScienceBook : Book {}

public void Export(string FileName, IList<Book> Data)

or you can use interface for it. e.g. interface IBook {}

like image 21
weeyoung Avatar answered Jan 21 '23 16:01

weeyoung