我想制作一个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
或者可能有一个数组或不同的集合类,它们不需要类型参数?
编辑:此问题专门针对关于类的结构,不。我完全清楚这可以用类和继承来解决,但我根本不能自由地使用类(第三方库问题......)。
答案 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;,每个只需要x
和y
,但有些操作需要更多信息,可以定义结构:
structure DrawListEntry {public int X,Y; public DrawOperation Op;}
对于moveto
和lineto
条目,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());
等