是否有可能列出不同的结构?

时间:2014-05-08 10:12:05

标签: c# list types struct

我想制作一个List,其中我可以放置多个不同的结构。问题是我不能给List模板参数,因为结构没有共同点(并且结构的继承是不可能的)。我的意思是以下内容:

struct Apple
{
    float roundness;
    float appleness;
}

struct Orange
{
   float orangeness;
   bool isActuallyAMandarin;
}

List<???> fruitBasket;

void Main(string [] args)
{
    fruitBasket = new List<???>();
    fruitBasket.Add( new Apple());
    fruitBasket.Add( new Orange());
}

出于显而易见的原因,退出List的模板参数会出现错误:

Using the generic type 'System.Collections.Generic.List<T>' requires 1 type arguments

有没有办法做到这一点?也许使用List或者可能有一个数组或不同的集合类,它们不需要类型参数?

编辑:此问题专门针对关于类的结构,。我完全清楚这可以用类和继承来解决,但我根本不能自由地使用类(第三方库问题......)。

6 个答案:

答案 0 :(得分:2)

每个结构都有一个基类:它是Object,所以你可以把它放在

  List<Object> fruitBasket;

但它意味着装箱列表中的每个结构。另一种可能性是

  List<ValueType> fruitBasket;

答案 1 :(得分:2)

你可以在这里使用接口!

public interface IFruit {}

Apple : IFruit {...}

Orange : IFruit {...}

List<IFruit> list = new List<IFruit>();
list.Add(new Apple());
list.Add(new Orange());

虽然,它仍会导致装箱操作(界面为引用类型)

答案 2 :(得分:1)

尚未提及的另一种可能性是定义一个结构,该结构包含足够的字段来封装任何所需结构可以容纳的所有值,以及确定如何解释它们的方法。例如:

struct AppleOrOrange {     float applenessOrOrangeness;     int roundnessOrMandarinness; }

由于某些位模式永远不会被float上的任何操作所产生,因此可以为普通话和非橘子保留两位模式,并说如果roundnessOrMandarinness持有其中一种模式这些位模式元素应该被视为橙色;它保持另一个,该值应按位转换为float,并将该元素视为苹果。请注意,在这种特殊情况下,这种方法将大大节省内存需求而不是装箱所有内容(拳击会使x86中的存储要求增加一倍以上[20 vs 8],并且在x64 [32 vs 8]中将它们翻两番)。

如果大多数项目很简单但有一些复杂的项目,那么另一种方法是使用一个结构,其中包含一个简单的&#34;简单的&#34;项目以及补充信息的参考类型。例如,如果有一个绘图操作列表,最常见的是&#34; moveto&#34;或者&#34; lineto&#34;,每个只需要xy,但有些操作需要更多信息,可以定义结构:

structure DrawListEntry {public int X,Y; public DrawOperation Op;}

对于movetolineto条目,op将包含对单身人士的引用;对于像ShowBitmap这样的条目,它可以包含对封装任意附加信息的非单例对象的引用。如果90%的绘图条目是&#34;移动到&#34;或&#34; lineto&#34;,这种方法每个需要12或16个字节,而不是24或32]。减少大部分参赛作品的存储成本的一半将是一个巨大的胜利。此外,var it=myList[index]; it.Op.Draw(it.X, it.Y)的缓存性能,其中it.Op在90%的时间内识别出两个单例中的一个,可能比在完全独立的对象实例上调用it.Draw()更好。

答案 3 :(得分:0)

虽然您的问题已得到解答,但我建议您也浏览StackOverflow的THIS帖子。它会让你清楚地了解很多东西。

在C#中,您可以使用接口来实现类似于多态与值类型(结构)的东西,因为您无法直接从结构派生,但您可以使用多个结构类型实现特定的接口。

因此,您可以使用 IFruits 来代替您的抽象结构 Fruit

答案 4 :(得分:0)

没问题。你只需创建一个对象列表。你可以使用一个老式的非泛型ArrayList,就像我们在.Net 1.x的旧时代做的那样,或者使用泛型List。它起作用,因为对象是一切的根源。

void Main(string [] args) {
  var fruitBasket = new List<Object>();
  fruitBasket.Add( new Apple());
  fruitBasket.Add( new Orange());
}

void Main(string [] args) {
  var fruitBasket = new ArrayList();
  fruitBasket.Add(new Apple());
  fruitBasket.Add(new Orange());
}

将事情排除在列表之外是另一个问题,但你没有问过,是吗?

答案 5 :(得分:-3)

如果struct不是唯一的选项,您应该尝试使用继承:

abstract class Fruit {
}

class Apple : Fruit {
}

class Orange : Fruit {
}

List<Fruit> fruits = new List<Fruit>();
fruits.Add(new Apple());