5

这就是我所拥有的:

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
}

有没有办法在不失去代码可读性的情况下完成这项工作,或者我应该尝试使用类而不是对象数组?

4

7 回答 7

4

您需要这样做(运算符优先级问题)

((Vector2)item[0]).X;

但是我不认为在同一个数组中有不同的对象类型是一个好习惯。这就是引入泛型 List 的原因(ArrayList 缺乏类型安全性)。

您的代码正在尝试执行以下操作:

ArrayList vectors = new ArrayList { new Vector2(22, 33), new Vector4(223, 43, 444, 33}};

这是在 .Net 2.0 之前。这引起了一些问题。

于 2012-07-09T18:30:14.077 回答
1

我会编写类而不是使用内置结构Vector2Vector4并让它们实现一个通用接口。这使您可以在声明数据结构时使用特定类型,而不是使用 type object

尝试这样的事情:

public class MyVector2 : IVector {

    //...
}

public class MyVector4 : IVector {

    //...
}

public interface IVector {


}

然后声明你的结构如下:

List<IVector> list = new List<IVector>();
IVector[] arr = new IVector[someSize];

如果类型Vector2Vector4是一些自定义类型而不是System.Windows.Vector2System.Windows.Vector4from 您可以对它们进行子类化并按照上述相同的方式进行操作:

public class MyVector2 : Vector2, IVector {

}

public class MyVector4 : Vector4, IVector {

}

只是一个提议。

于 2012-07-09T18:33:45.567 回答
1

如果您使用的是 .NET 4 并且不想创建新类,则可以使用 Tuple:

List<Tuple<Vector2, Vector4>> markers = new List<Tuple<Vector2, Vector4>>();
于 2012-07-09T18:35:17.847 回答
1

你在做什么是可怕的。你为什么不编程到一个接口并遍历它的列表。那么你就不需要演员了,你可以根据你的合同做其他事情。在这种情况下,您并不真正知道哪个对象是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();

      ....
}
于 2012-07-09T18:35:19.857 回答
1

您绝对应该重构它以使用类。基本上,您需要一个标记列表,每个标记可以包含一个或多个包含一个或多个数字的向量。这是在不使用继承的情况下实现它的简单方法:

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>.

于 2012-07-09T18:36:57.037 回答
1

我决定和 Tuple 一起去。感谢后来删除答案的海报的想法。你的英勇事迹将被铭记。

编辑:必须更改Vector4Color(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 效率,如果这被证明比其他建议的解决方案慢,我会考虑使用它们。

于 2012-07-09T19:29:47.273 回答
0

这里可能是一个很好的起点:

public class Markers
{
    public Vector2 V2 { get; set; }
    public Vector4 V4 { get; set; }

    public Markers() {}
}
于 2012-07-09T18:34:59.860 回答