【问题标题】:Is it possible for a non-generic class contain a generic list in .NET (C# or VB.NET)?非泛型类是否可以在 .NET(C# 或 VB.NET)中包含泛型列表?
【发布时间】:2012-08-19 00:33:34
【问题描述】:

我希望有人可以帮助我了解这样的事情是否/如何可能。

在这种情况下,假设您正在尝试为电子表格或数据库中的网格建模,但每列中的数据只能是一种数据类型。

示例:第 1 列只能包含整数。

我创建了一个通用类来模拟如下所示的列结构:

public class CollectionColumn<T>
{
private string _name;
private string _displayName;

private List<T> _dataItems = new List<T>();

public string Name {
    get { return _name; }
    set { _name = value; }
}

public string DisplayName {
    get { return _displayName; }
    set { _displayName = value; }
}


public List<T> Items {
    get { return _dataItems; }
    set { _dataItems = value; }
}
}

现在我想做的是为各种列(可能有 CollectionColumn、CollectionColumn 等)提供一个容器,并拥有它自己的属性,但我不确定如何在仍然可以访问列的情况下执行此操作以及当我不知道它们的类型时它们中的数据。

这是一个 .NET 2.0 项目,所以像动态这样的东西不起作用,也许是对象列表?我也不确定是否有办法使用接口来做到这一点。

public class ColumnCollection
{
public int Id { get; set; }
public string ContainerName { get; set; }

private List<CollectionColumn<T>> _columns;
public List<CollectionColumn<T>> Columns {
    get { return _columns; }
    set { _columns = value; }
}

}

我希望能够将各种 CollectionColumn 添加到 ColumnCollection 的 Columns 集合中,这样我就可以拥有包含各种类型数据的列。

非常感谢任何帮助。

【问题讨论】:

  • 你真的要这样暴露List&lt;T&gt;吗?一般来说,如果一个类要公开一个类类型的属性,它应该(1)被认为是识别而不是包含它所引用的对象,(2)它应该是对不可变对象的可能可变引用对象,或者 (3) 它应该是对可能可变对象的不可变引用。从外观上看,您的专栏将把 List&lt;T&gt; 的内容视为自己的内容(因此第 1 点不符合条件),引用是可变的(第 2 点),List&lt;T&gt; 是可变的(第3).
  • 这是一个危险的模式,因为设置引用指向它自己的列表的对象无法知道其他对象是否会尝试改变该引用引用的列表,也不知道任何想要改变该对象持有的列表的对象,以了解对该列表的引用是否被任何期望它不会改变的东西持有。

标签: c# .net vb.net generics c#-2.0


【解决方案1】:

这是一个相当普遍的问题。您需要做的是声明一个泛型类继承自的非泛型基类或泛型类实现的非泛型接口。然后,您可以制作该类型的集合。

例如,

public abstract class CollectionColumnBase
{
    private string _name;
    private string _displayName;

    public string Name {
        get { return _name; }
        set { _name = value; }
    }

    public string DisplayName {
        get { return _displayName; }
        set { _displayName = value; }
    }

    public abstract object GetItemAt(int index);
}

public class CollectionColumn<T> : CollectionColumnBase
{
    private List<T> data = new List<T>();

    public overrides object GetItemAt(int index)
    {
        return data[index];
    }

    public List<T> Items
    {
        get { return data; }
        set { data = value; }
    }
}

public class ColumnCollection
{
    public int Id { get; set; }
    public string ContainerName { get; set; }

    private List<CollectionColumnBase> _columns;
    public List<CollectionColumnBase> Columns {
        get { return _columns; }
        set { _columns = value; }
    }
}

【讨论】:

  • 谢谢亚当。我刚刚制作了 CollectionColumnBase 抽象并在 ColumnCollection 构造上新建了 CollectionColumnBase 列表,因此它永远不会为空。再次感谢!
  • @jon333:是的,你需要做这些事情。我会修改答案;谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
  • 2010-12-02
  • 1970-01-01
  • 2016-10-05
  • 1970-01-01
相关资源
最近更新 更多