这就是我所拥有的:
List<object[]> markers = new List<object[]>();
object[] marker = new object[2];
marker[0] = new Vector2(1, 2);
marker[1] = new Vector4(1, 2, 3, 4);
markers.Add(marker);
foreach (var item in markers)
{
int x = (Vector2)item[0].X; // Error: 'object' does not contain a definition
// for 'X' and no extension method 'X' accepting
// a first argument of type 'object' could be
// found (are you missing a using directive or
// an assembly reference?)
// other stuff
}
有没有一种方法可以在不损失代码可读性的情况下实现这一点,或者我应该尝试使用类而不是对象数组?
您需要这样做(操作员优先级问题)
((Vector2)item[0]).X;
然而,我认为在同一个数组中使用不同的对象类型不是一个好的做法。这就是引入泛型List的原因(ArrayList缺乏类型安全性)。
您的代码正在尝试执行以下操作:
ArrayList vectors = new ArrayList { new Vector2(22, 33), new Vector4(223, 43, 444, 33}};
这是在.Net 2.0之前。它造成了一些问题。
如果您正在使用.NET4,并且不想创建新的类,那么Tuple就是您可以使用的:
List<Tuple<Vector2, Vector4>> markers = new List<Tuple<Vector2, Vector4>>();
你正在做的事情很糟糕。为什么不编程到一个接口,并在列表中迭代呢。然后你就不需要选角了,你可以根据合同做其他事情。在这种情况下,您并不真正知道哪个对象是vector2或vector4。好吧,你可以发现,但那真的很难看。
这将更加灵活、可扩展和可维护。我真的不知道你在做什么,但我愿意接受。
我会做以下事情:
interface IVector<T>
{
List<T> Someobjectcollections
void YourCommonOperation()
}
class Vector2 : IVector<Vector2>
{
// override
}
class Vector4 : IVector<Vector4>
{
// override
}
List<IVector> markers = new List<IVector>();
...
foreach (var item in markers)
{
items.commonoperation();
....
}
您绝对应该重构它以使用类。基本上,您需要一个标记列表,每个标记都可以包含一个或多个向量,这些向量依次包含一个或者多个数字。这是一种在不使用继承的情况下实现它的简单方法:
public class Marker
{
public List<Vector> { get; set; }
}
public class Vector
{
public int[] Numbers { get; private set; }
public Vector(params int[] numbers)
{
Numbers = numbers;
}
}
然后,您可以简单地使用List<Marker>
。
我会编写类,而不是使用内置的结构Vector2
和Vector4
,并让它们实现一个公共接口。这使您能够在声明数据结构时使用特定类型,而不是使用类型object
。
试试这样的东西:
public class MyVector2 : IVector {
//...
}
public class MyVector4 : IVector {
//...
}
public interface IVector {
}
然后声明您的结构如下:
List<IVector> list = new List<IVector>();
IVector[] arr = new IVector[someSize];
如果类型Vector2
和Vector4
是一些自定义类型,而不是来自的System.Windows.Vector2
和System.Windows.Vector4
,则可以对它们进行子类化,并按照上述步骤进行:
public class MyVector2 : Vector2, IVector {
}
public class MyVector4 : Vector4, IVector {
}
只是一个提议。
我决定和Tuple一起去。感谢发帖人的想法,他后来删除了自己的答案。你的英勇事迹将被铭记。
编辑:必须将Vector4
更改为Color
(alpha通道始终为255)。
结果:
// declaration
List<Tuple<Vector2, Color>> markers = new List<Tuple<Vector2, Color>>();
// adding items
Tuple<Vector2, Color> marker = new Tuple<Vector2, Color>(
new Vector2(x, y), Color.FromNonPremultiplied(250, 200, 150, 100));
markers.Add(marker);
// retrieving item values
foreach (var item in markers)
{
int x = item.Item1.X;
int y = item.Item1.Y;
Color mycolor = item.Item2;
}
它是有效的,但我还没有测试CPU效率,如果这比其他提出的解决方案慢,我会考虑使用它们。
这里可能是一个很好的起点:
public class Markers
{
public Vector2 V2 { get; set; }
public Vector4 V4 { get; set; }
public Markers() {}
}