Приведение объекта [] к типу [] через отражение

Цель

У меня есть объект []Source, объект Target и FieldInfo Var (Var.FieldType.IsArray имеет значение true). Я хочу запустить Var.SetValue(Target,Source). Однако я не могу преобразовать "object[]" -> "anotherType[]"

Пробный запуск

object[]Source=new object[2]{"Hello","World"};
Var.SetValue(Target,Source); //Cannot Convert "object[]"->"string[]"

[примечание: я хочу иметь возможность использовать целые числа, двойные числа, числа с плавающей запятой и т. д. В противном случае эта проблема была бы тривиально простой]

Исследования

Использовать переменную: нельзя использовать, так как нельзя создавать массивы переменных.

Использовать обобщения:

Это работает для

myField.SetValue(target,GenericCastArray<string>(source));

Однако он не работает для

Type someType=typeof(string); //or int, or float
 (myfield.SetValue(target,GenericCastArray< someType > (source))

* http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/fe14d396-bc35-4f98-851d-ce3c8663cd79/* возвращает исключение нулевой ссылки, я думаю, в this.GetType()

EDIT: Meh Solution Судя по комментариям, невозможно преобразовать объект[] в строку[]. Однако следующий код работает достаточно хорошо.

object[]Source=null;
Type basetype=Var.FieldType.GetElementType();
int l=somelength;
if (basetype.IsEquivalentTo(typeof(string))) Source = new string[l];
//repeat for all types

source=//run your Reflection here

var.SetValue(target,source); 

person Dennis Benson    schedule 28.07.2012    source источник
comment
Есть ли причина, по которой источник должен быть объектом []? Нет ли способа сделать исходный код универсальным и, следовательно, не нужно делать приведение? Можете ли вы объяснить, что вы используете для этого? Вы можете делать общие приведения в общем классе, так что это может быть что-то вроде того, что вы хотите...   -  person Charleh    schedule 28.07.2012
comment
Честно говоря, то, что вы пытаетесь сделать, не сработает. Вы можете использовать дженерики только в том случае, если вы знаете достаточно о типе во время компиляции. Вы явно не знаете, какой тип вам дан, до времени выполнения (до someType).   -  person Jeff Mercado    schedule 28.07.2012
comment
@Charleh Я пытаюсь использовать Reflection для сериализации массивов строк/целых/двойных значений/и т. д. Спасибо за предложение сделать Source универсальным, хотя я немного озадачен тем, как это сделать. Я буду исследовать это.   -  person Dennis Benson    schedule 28.07.2012
comment
Какая подпись у SetValue()? Вы можете использовать отражение здесь, но это совершенно другой зверь.   -  person Jeff Mercado    schedule 28.07.2012
comment
Можете ли вы вдаваться в подробности и, возможно, опубликовать, что вы пытаетесь сериализовать, почему вы пытаетесь это сделать, из какого объекта вы сериализуете, какой объект вы пытаетесь десериализовать и, возможно, поместите часть кода. Обычно использование отражения для чего-то подобного означает, что вы, вероятно, не подходите к этому правильно.   -  person Charleh    schedule 28.07.2012
comment
@JeffMercado Спасибо. Я думал, что может быть так. В этом случае я не думаю, что ответ Чарле тоже сработает, верно?   -  person Dennis Benson    schedule 28.07.2012
comment
@Charleh, я отредактирую свой пост с подробностями   -  person Dennis Benson    schedule 28.07.2012
comment
Сериализация объекта должна позволять восстановить объект на другом конце любого канала связи, через который вы сериализовали. Как вы сериализуете? Вы отметили сериализуемый объект? Вы используете XmlSerializer или BinaryFormatter? Какой сетевой метод вы используете для передачи? Вы используете сокеты? UDP? ПТС?   -  person Charleh    schedule 28.07.2012
comment
Похоже, вы не используете встроенные методы сериализации в .NET? Увидев, что вы используете отражение для обнаружения информации о полях, вы также можете использовать сериализаторы .NET. Разве это не то, что вы пробовали?   -  person Charleh    schedule 28.07.2012
comment
Спасибо за помощь Чарле. У меня нет опыта работы с сериализаторами фреймворка. Я использую внешнюю библиотеку, которая очень хорошо обрабатывает сериализацию. Я выбрал не драматичное решение.   -  person Dennis Benson    schedule 28.07.2012


Ответы (1)


Невозможно преобразовать массив одного типа в массив другого типа (т. е. object[] в string[]), потому что это разные несовместимые типы. Отражение тоже не поможет кастовать.

Для преобразования вам всегда нужно будет создать какую-то копию массива либо напрямую, либо путем создания IEnumerable<DestinationType> с помощью одной из функций преобразования LINQ.

person Alexei Levenkov    schedule 28.07.2012
comment
Ну, это не так просто. Вы можете использовать, например. от string[] до object[] благодаря ковариации массива. (Хотя ковариация массивов — плохая идея, и в .Net она есть только потому, что она хочет быть совместимой с Java.) - person svick; 28.07.2012
comment
... и ковариация массивов работает только между массивами ссылочных типов. Он вообще не работает для массивов типов значений. - person Jeff Mercado; 28.07.2012