4

具体来说,我想编写一个可以像这样使用的导出函数:

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

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

我想到了类似下面的代码,但在这种情况下,我必须将所有内容都转换为“对象列表”,这不是我想要的。

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

你能给我一个提示如何优雅地解决这个问题吗?

4

3 回答 3

4
class Book {}

class ScienceBook : Book {}

class MathBook : Book  {}

class ScienceBook : Book {}

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

或者你可以使用它的界面。例如界面 IBook {}

于 2012-04-03T06:45:32.200 回答
4

如您所说,如果您希望能够传递完全不相关的列表,也许您应该接受基本的 IList 接口:

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

所有List<T>对象都实现IList,以及泛型IList<T>,因此您可以强制执行。

实际上,根据您需要在导出器中对这些列表执行IEnumerable的操作,如果您只需要只转发一次的只读功能,那么强制执行对您来说就足够了。

最好的决定方法是确定所有参数所需的共享功能,并定义方法签名以强制执行该功能。

更新

根据您的评论,在 C# 4.0 中使用协变/逆变泛型似乎可以实现您想要的,这意味着泛型ISomething<out object>可以接收ISomething<string>. 问题是它IList<T>没有定义协变泛型参数,因此传递IList<string>forIList<object>不起作用。

但是,IList<T>inherits IEnumerable<out T>,它确实定义了一个协变参数。所以如果你的Export方法接收到一个params IEnumerable<object>[] data参数,你应该能够传递任何IList<T>你想要的。

于 2012-04-03T06:51:46.520 回答
1
   public interface IBook {}

   public class ScienceBook : IBook {} 
   public class MathBook: IBook {}
   public class HistoryBook: IBook {}

    class Main()
    {
      List<IBook> hbook = new List<HistoryBook>();
      List<IBook> mbook = new List<MathBook>();
      List<IBook> sbook = new List<ScienceBook> ();

      public void Export(string FileName, List<IBook> Data)


    }
于 2012-04-03T06:53:47.783 回答