5

This is what I have:

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
}

Is there a way to make this work without losing code readability, or should I try using a class instead of object array?

5
  • 1
    A class would be much better than an object array. Commented Jul 9, 2012 at 18:31
  • 3
    Sure thing! Use classes to express it clearer and more readable. Commented Jul 9, 2012 at 18:32
  • 4
    And then you'll get an InvalidCastException because you cannot cast a Vector4 to a Vector2 (at least, I found no common ancestry between the two on MSDN). Commented Jul 9, 2012 at 18:32
  • What is the point of the 'marker' object? I could be mistaken, but it seems you have an extra object layer that is only making it confusing. Commented Jul 9, 2012 at 18:32
  • @naspinski I'm making a debug method that draws markers at specific coordinates and of user-defined color when certain conditions are met. Commented Jul 9, 2012 at 18:35

7 Answers 7

4

You need to do this (operator precedence issue)

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

However I don't think it is good practice to have different object types in the same array. That's why generic List has been introduced ( lack of type safety with ArrayList).

Your code is trying to do something like :

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

This was before .Net 2.0. And it was causing some problems.

Sign up to request clarification or add additional context in comments.

1 Comment

Strangely, when I first tried this, it didn't work either, but after reloading the project it did. Realoading project has saved me many times before :p
1

If you're using .NET 4 and don't wan't to create a new class, Tuple is what you can use:

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

Comments

1

what u are doing is terrible. why dont u program to an interface and iterate through list of that. then you wont need casting and you can do other stuff based on your contract. in this case, you dont really know which object is vector2 or vector4. well you can find out but it would be really ugly.

This would be more flexible, extensibe and maintainable. I dont really know what u are doing but i would go with this.

I would do something as follows:

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();

      ....
}

2 Comments

and what you are doing is copying answers justkidding ;)
lool. i just commented that to u. u are like steve jobs dude. u copied mine.
1

You should absolutely refactor this to use classes. Basically, you need a list of markers, each of which can hold one or more vectors that contain one or more numbers in turn. This is a simple way to achieve it without using inheritance:

public class Marker
{
    public List<Vector> { get; set; }
}

public class Vector
{
    public int[] Numbers { get; private set; }

    public Vector(params int[] numbers)
    {
        Numbers = numbers;
    }
}

Then, you can simply use List<Marker>.

Comments

1

I would write classes instead of using the built-in structs Vector2 and Vector4 and let them implement a common interface. That enables you to use a particular type when declaring your data structures instead of using type object.

Try something like this:

public class MyVector2 : IVector {

    //...
}

public class MyVector4 : IVector {

    //...
}

public interface IVector {


}

Then declare your structure as follows:

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

In case the types Vector2 and Vector4 are some custom types rather than being System.Windows.Vector2 and System.Windows.Vector4 from you can subclass them and proceed in the same as described above:

public class MyVector2 : Vector2, IVector {

}

public class MyVector4 : Vector4, IVector {

}

Just a proposal.

2 Comments

Vector2 is a struct, so it can't be extended. msdn.microsoft.com/en-us/library/…
i thought vector2 is a class that user created. didnt know it s related to XNA framework.
1

I decided to go with Tuple. Thanks for the idea to the poster who later removed his answer. Your deeds of valor will be remembered.

Edit: had to change Vector4 to Color (alpha channel was always 255).

Result:

// 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;
}

It works, but I still haven't tested for CPU efficiency, if this proves to be slower than other proposed solutions, I will consider using them instead.

Comments

0

Here might be a good starting point:

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

    public Markers() {}
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.