通用列表中的属性名称相同但返回类型不同

时间:2009-11-26 11:53:15

标签: c# generics collections

初学者的问题:如何实现通用列表List<Item>返回具有名为Data的属性的项目,但为不同的子类返回不同的类型?我开始构建以下层次结构,但这不会导致目标。

abstract class Item
abstract class ItemGeneric<TData> : Item
class ItemText : ItemGeneric<string>
class ItemImage : ItemGeneric<Image>

我创建了一堆ItemText和ItemImage类的实例,并将它们添加到通用List<Item>列表中。但是,一旦我浏览了列表并希望检索Data属性,就无法访​​问它(显然)它只在ItemGeneric<TData>类层次结构级别而不是在Item类中实现。

我想在不使用System.Object来避免强制转换的情况下解决此问题。

有没有解决这个问题的常见模式?

4 个答案:

答案 0 :(得分:1)

如果我理解这个问题,我不能100%确定。

我通常使用带有无类型属性的接口:

interface IUntypedItem
{
  object UntypedData {get; }
}

interface IItem<T> : IUntypedItem
{
  T Data {get; set;}
}

class abstract ItemGeneric<T> : IItem<T>
{
  T Data { get; set; }
  object UntypedData { get { return Data; }}
}

class ItemText : ItemGeneric<string>
{

}

然后你可以拥有UntypedItems

的列表
List<IUntypedItem> list;
foreach (IUntypedItem item in list)
{
  // use item.UntypedData
  // or downcast to use typed property
}

如果要在同一列表中处理不同类型,则无法避免转换或对象。你可以说明你在做什么。

答案 1 :(得分:1)

如果您对包含类之外的类型数据执行某些功能,那么您需要预先知道该类型。

不太好:

foreach (Item item in list)
{
    ItemGeneric<int> intItem = item as ItemGeneric<int>;
    if (intItem != null)
    {
        //do stuff
    }
}

您可以通过将功能移动到包含数据的类中来解决此问题。

(见encapsulation

所以,您可以像这样使用您的列表:

foreach (Item item in list)
{
    item.DoStuff();
}

这意味着您需要在Item类上使用DoStuff:

public abstract class Item
{
    public abstract void DoStuff();
}

..并且可以在ItemGeneric上实现它:

public class ItemGeneric<T> : Item
{
    public T Data { get; set; }

    public override void DoStuff()
    {
        //do generic typed stuff here
        Console.WriteLine(Data);
    }
}

答案 2 :(得分:0)

这样的东西?

public class ItemGeneric<T> {

  private List<T> data;

}

public class ItemText : ItemGeneric<String> { ... }

public class ItemImage : ItemGeneric<Image> { ... }

在Java中你可以将超类定义为泛型类型T,我不知道它在C#中是如何工作的

public class ItemGeneric<T extends IData> {

 private List<T> data;
}

答案 3 :(得分:0)

这是你在BaseClass中创建一个函数的方法,当从derivedclass类型的对象调用时返回DerivedTypes的集合,没有魔法只是泛型。这个例子讨论了HashSet,在你的情况下它可以是你想要的任何类型。

//**The BaseClass**
public class BaseClass<T>
    where T : BaseClass<T>
{
    public HashSet<T> GetHashSet()
    {
        HashSet<T> hSet = new HashSet<T>();
        //create a HashSet<T>
        //do some work
        //and return;
        return hSet;
    }
}

//**The Derived Class**
public class DerivedClass : BaseClass<DerivedClass>
{
    //you have the method inherited.
}