0

I have an array of MyType s in an object similar to the setup below, I want to be able to set the value of an index on myObject as it is, I cannot change the declaration of MyFunction.

/*...*/
MyType [] myTypedArray = new MyType[100];
MyFunction(myTypedArray);
/*...*/

function MyFunction(object myObject)
{
    myObject[0] = new MyType();
}

This, obviously, doesn't work but I cannot figure out how to get it to work. I cannot cannot use templates/generics it has to be all using reflection.

Note that I have to have myObjectArray, initially, as an "object" as this is how I receive it. I cannot do the initial cast to a object[]. I have tried casting myObjectArray to object[] and it doesn't work.

I also do not have access to MyType as a static type, only runtime.

Any advice would be great, thanks.

1
  • How can you new() it if you don't have the type? Commented Nov 16, 2009 at 20:34

5 Answers 5

4

Declare myObjectArray as an array of objects:

object[] myObjectArray = myTypedArray;
myObjectArray[0] = new MyType(); // okay to go!

Alternatively, if for some reason myObjectArray must be an object you can say:

((object[])myObjectArray)[0] = new MyType();

These are smelly though. And beware of array covariance in C#!

Here's an implementation along the lines that you seem to be looking for:

void AddToArray(object array, int index) {
    if(array == null) {
        throw new ArgumentNullException();
    }
    Type arrayType = array.GetType();
    if(!arrayType.IsArray) {
        throw new InvalidOperationException("array must be an Array");
    }

    (Array)asArray = (Array)array;
    if (index < 0 || index >= asArray.Length) {
        throw new ArgumentOutOfRangeException("index");
    }
    object newInstance = Activator.CreateInstance(elementType);
    asArray.SetValue(newInstance, index);
}

Invoke as:

AddToArray(myObjectArray, 0);

This assumes that elementType has a parameterless constructor. There are ways around this, but this should be enough to get you started. This method also probably needs a better name.

Again, this code is very smelly. I would suggest taking a step back and seeing if you can solve your problem using strongly-typed code.

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

6 Comments

I have clarified question, I have no control over how I originally see myObjectArray - it comes in as an object not an object[]
@Chris: See comment beginning with "Alternatively, if for some reason...".
Thanks Jason. However I tried something similar and I got an error "Unable to cast object of type 'System.Boolean[]' to type 'System.Object[]'."
@Chris: Yeah, that's because bool is a value type. The CLR will never let you cast an array where the elements are value types to any other array type. So string[] strings = new string[n]; object o = strings; object[] array = (object[])o; is legal but bool[] bools = new bool[n]; object o = bools; object[] array = (object[])o; is not.
Any idea what I can do then? The array type could be anything? (Note this is for my own serialization stuff)
|
1

You can cast the object to an Array and call SetValue on it, for a completely non-object-specific way of doing it. This'll box & unbox value types as appropriate & do all the necessary array type checking.

Comments

1

Try something like:

DayOfWeek[] myTypedArray = Enum.GetValues(typeof(DayOfWeek))
                               .OfType<DayOfWeek>().ToArray();
object myObject = myTypedArray;

object[] myObjectArray =   // from object to object[]
        (myObject as Array ?? new object[0]).OfType<object>().ToArray();

Type type = myObjectArray[0].GetType(); // unbox type
myObjectArray[0] = Activator.CreateInstance(type); // create another instance

Note you'll lose type safety.

Comments

0

In this case, you need a cast to object[]:

((object[])myObjectArray)[0] = new MyType();

1 Comment

OP says he can't cast to object[]
0

((MyType[])myObjectArray)[0] = new MyType(); perhaps?

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.