Установка значений массива, не зная его типа - PullRequest
0 голосов
/ 16 ноября 2009

У меня есть массив MyType s в объекте, похожем на настройку ниже, я хочу иметь возможность установить значение индекса для myObject как есть, я не могу изменить объявление MyFunction.

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

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

Это, очевидно, не работает, но я не могу понять, как заставить это работать. Я не могу не использовать шаблоны / дженерики, все должно быть с помощью отражения.

Обратите внимание, что сначала я должен иметь myObjectArray в качестве «объекта», поскольку именно так я его получаю. Я не могу выполнить первоначальное приведение к объекту []. Я попытался привести myObjectArray к object [], и он не работает.

У меня также нет доступа к MyType как статическому типу, только во время выполнения.

Любой совет был бы великолепен, спасибо.

Ответы [ 5 ]

4 голосов
/ 16 ноября 2009

Объявите myObjectArray как массив object s:

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

В качестве альтернативы, если по какой-то причине myObjectArray должно быть object, вы можете сказать:

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

Хотя они вонючие. И остерегайтесь ковариации массива в C # !

Вот реализация в том же духе, которую вы, похоже, ищете:

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

Вызывать как:

AddToArray(myObjectArray, 0);

Предполагается, что elementType имеет конструктор без параметров. Есть способы обойти это, но этого должно быть достаточно, чтобы вы начали. Этот метод также, вероятно, нуждается в лучшем названии.

Опять же, этот код очень вонючий. Я бы предложил сделать шаг назад и посмотреть, сможете ли вы решить свою проблему, используя строго типизированный код.

1 голос
/ 16 ноября 2009

Вы можете привести объект к Array и вызвать на нем SetValue для совершенно не специфичного для объекта способа сделать это. Это будет блокировать и распаковывать типы значений соответствующим образом и выполнять всю необходимую проверку типов массивов.

1 голос
/ 16 ноября 2009

Попробуйте что-то вроде:

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

Обратите внимание, вы потеряете безопасность типов.

0 голосов
/ 16 ноября 2009

((MyType[])myObjectArray)[0] = new MyType(); возможно?

0 голосов
/ 16 ноября 2009

В этом случае вам нужен приведение к object[]:

((object[])myObjectArray)[0] = new MyType();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...