访问foreach循环</object []>中List <object []>的数组元素

时间:2012-07-09 18:28:53

标签: c# object foreach

这就是我所拥有的:

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
}

有没有办法让这项工作不失代码可读性,或者我应该尝试使用类而不是对象数组?

7 个答案:

答案 0 :(得分:4)

您需要执行此操作(运算符优先级问题)

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

但是我不认为在同一个数组中使用不同的对象类型是一种好习惯。这就是为什么引入了通用List(缺少使用ArrayList的类型安全性)。

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

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

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

答案 1 :(得分:1)

我会编写类而不是使用内置结构Vector2Vector4,并让它们实现一个通用接口。这使您可以在声明数据结构时使用特定类型,而不是使用类型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.Vector4,您可以将它们子类化并继续执行上述操作:

public class MyVector2 : Vector2, IVector {

}

public class MyVector4 : Vector4, IVector {

}

只是提案。

答案 2 :(得分:1)

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

List<Tuple<Vector2, Vector4>> markers = new List<Tuple<Vector2, Vector4>>();

答案 3 :(得分: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();

      ....
}

答案 4 :(得分: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>即可。

答案 5 :(得分:1)

我决定和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效率,如果这被证明比其他提议的解决方案慢,我会考虑使用它们。

答案 6 :(得分:0)

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

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

    public Markers() {}
}