【问题标题】:A collection of any type任何类型的集合
【发布时间】:2018-05-31 12:07:31
【问题描述】:

我正在开展一个项目,该项目将从提供的数据生成 Excel 文件。 Book 类有多个Sheet 类,每个Sheet 类包含一个对象列表。但是,不同的工作表可能具有不同类型的数据。

即第一张可能是List<Dog>,第二张可能是List<Planet>

这个想法是从 EF 获取不同的结果集,创建一本新书,为每个结果集添加一个工作表,然后让应用程序创建 Excel 文件。

使用泛型(我很陌生)给我带来了一些问题。

public class Book
{
    public List<Sheet> Sheets { get; set; }
}

public class Sheet
{
    public string Name { get; set; }
    public List<T> Data { get; set; }
}

这不起作用,因为“找不到T”,所以我换了表格

public class Sheet<T>
{
    public string Name { get; set; }
    public List<T> Data { get; set; }
}

但是 Book 需要了解 T,这使得我的 Sheet 列表只有一种类型。

我尝试了接口路由,并将这两个属性添加到接口,但这(再次)导致我不得不提供 T。

public interface ISheet
{
    string Name { get; set; }
    List<T> Data { get; set; }
}

我确信我遗漏了一些明显的东西,而且我把它弄得太复杂了。

谢谢

[编辑:在一个示例中,我使用了'List&lt;Book&gt;',但我意识到这很混乱,所以我将其更改为'List&lt;Planet&gt;']

【问题讨论】:

  • 奇怪的问题 => Dog 和 Book 有什么共同点吗?
  • 类型系统和您遇到的错误正试图将您从自己手中拯救出来。即使您的第一次尝试 BookSheet 成功了,您也无法编写 type safe 代码来迭代 Sheets 并访问每个 Data 属性。
  • 假设你得到了这个工作,你希望如何在代码中使用它? (或另一种说法,达米安所说的!)
  • @CodeNotFound,不。它们可以是任何东西。
  • 基本上,当您创作通用代码时,您不知道要使用什么类型,但能够应用约束。当您使用泛型代码(编写使用现有泛型类型/方法的代码)时,您确实需要知道您正在使用的具体类型(除非您的代码本身就是通用的)。您正在尝试使用泛型类,但仍然不知道具体类型并且您自己不能是泛型的。

标签: c# generics collections


【解决方案1】:

您必须将通用与继承结合起来,一个简单的解决方案可能是:

public class Book
{
    public List<Sheet> Sheets { get; set; }
}

//Use sheet as a base class for specific Sheet
public abstract class Sheet
{
    public string Name { get; set; }
    public abstract IList Data { get; }
}

//Use the generic class to unify sheet management
public class SheetTyped<T> : Sheet
{        
    private List<T> _data { get; set; }
    public override IList Data { get { return _data; } }

    public SheetTyped(string sheetName, List<T> lData)
    {
        _data = lData;
        Name = sheetName;
    }
}

当然,您必须使用至少一种知道要创建的工作表类型并且看起来像这样的工厂方法:

public class Dog {
   string Name;
   public Dog(string name) { Name = name ; }
}
public class Cat {
   string Name;
   public Cat(string name) { Name = name ; }
}

public class test
{
    public Book MyBook ;
    public SheetTyped<Dog> AllMyDog ;
    public SheetTyped<Cat> AllMycat ;

    public void MyTest()
    {
        Dog[] InitDogs = { new Dog("Fuffy")
                         , new Dog("Puffy")
                         , new Dog("Alex") };
        Cat[] InitCats = { new Cat("Romeo")
                         , new Cat("July")
                         , new Cat("Briciola") };

        List<Dog> MyDogList = new List<Dog>(InitDogs);
        List<Cat> MyCatList = new List<Cat>(InitCats);

        AllMyDog  = new SheetTyped<Dog>( "My dogs", MyDogList ) ;
        AllMycat  = new SheetTyped<Cat>( "My cats", MyCatList ) ;
        MyBook    = new Book() ;
        MyBook.Sheets = new List<Sheet>(2);
        MyBook.Sheets[0] = AllMyDog  ;
        MyBook.Sheets[1] = AllMycat  ;
    }
}

我认为这行得通。 让我知道它是否对您有用。 再见

【讨论】:

    猜你喜欢
    • 2013-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    相关资源
    最近更新 更多