Приведение типа C # во время выполнения с использованием отражения - PullRequest
9 голосов
/ 01 декабря 2009

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

У меня есть файл XML, который описывает 1) пользовательский объект, производный от базового типа, и 2) имена внутренних полей и связанные значения. Эти производные объекты могут иметь дополнительные поля, о которых базовый класс не знает.

Я извлекаю тип объекта в виде строки и помещаю все данные объекта в словарь, где ключ - это имя поля, а значение - это значение поля. Я создаю экземпляр объекта, используя имя строки и конструктор объекта по умолчанию. Я могу вынюхнуть все свойства объекта в PropertyInfo [] . Теперь мне нужно взять все значения в строковой форме и преобразовать их в правильные типы данных, чтобы я мог загрузить их в свойства объекта. (Когда я набираю это, звучит так, будто я беру своего рода состояние сохранения и восстанавливаю его, но я слышал только об этом. Если вы хотите посоветовать в этом направлении, пожалуйста, имейте в виду, что Я застрял при чтении данных из файла XML и не могу этого изменить.)

Я могу преобразовать все строковые значения в тип, заданный объектом Type и используя созданную мной функцию грубой силы, имеющую следующее определение:

public object convertMe(string v, Type t)

Так как я не знаю, что Тип Я бросаю на функцию, я не знаю, что возвращается, и я не могу явно привести объект к правильный тип для присвоения вышеупомянутому свойству. Я пытался выполнить следующий тип забрасывания безрезультатно:

string objectType = /*read type string from XML*/;

... // Wherein I instantiate an object "theObject" and get PropertyInfo[] from it.
... // I also make sure that I'm trying to assign the correct data to
... // the correct property.

Type t = currentProperty.PropertyType;
object o = convertMe(value, Type.GetType(qtype));
currentProperty.SetValue(theObject, (t)o, null);  // Doesn't work
currentProperty.SetValue(theObject, (t)Convert.ChangeType(o, t), null);  // Doesn't work.  Apparently (t) is bad syntax.

В конечном счете, моя цель - создать экземпляр объекта и загрузить его с данными из файла XML таким образом, чтобы типы данных не были жестко закодированы. Причина, по которой я делаю это в C #, заключается в том, что раньше это была программа на Python, и мне было поручено перевести ее на C # .NET 2.0. Это опыт обучения, если не сказать больше. Причина, по которой я создал эту «функцию грубой силы», заключается в том, что я искал способ обойти эту проблему приведения, но, что бы я ни пытался, я не могу заставить ее работать. Я мог бы сделать это самостоятельно, используя чистую силу, но я подумал, что должно быть элегантное решение, которого мне не хватает.

Любая помощь очень ценится!

Ответы [ 2 ]

14 голосов
/ 01 декабря 2009

Тебе там вообще не нужен актерский состав. PropertyInfo.SetValue принимает аргумент типа object, поэтому просто передайте ему o, и это будет все.

5 голосов
/ 01 декабря 2009

Вам не нужен актерский состав вообще. Приведение полезно только тогда, когда вы пытаетесь иметь дело с объектами напрямую, а не когда вы используете отражение.

Когда вы устанавливаете свойство, вы используете PropertyInfo.SetValue . Это принимает object в качестве параметра значения, поэтому нет необходимости пытаться привести его к определенному типу (если объект уже имеет правильный тип).

Поскольку вы уже сделали "convertMe", который переводит объект в правильный тип (приведенный или помещенный в Object), все готово - просто используйте его.

...