Приведение объекта к T
я разбираю XML-файл с помощью XmlReader класс в .NET, и я подумал, что было бы разумно написать общую функцию синтаксического анализа для чтения различных атрибутов в целом. Я придумал следующую функцию:
private static T ReadData<T>(XmlReader reader, string value)
{
reader.MoveToAttribute(value);
object readData = reader.ReadContentAsObject();
return (T)readData;
}
как я понял, это не работает полностью, как я планировал; это вызывает ошибку с примитивными типами, такими как int или double, так как приведение не может преобразовать из string к числовому типу. Есть ли способ для моей функции превалировать в измененная форма?
8 ответов:
сначала проверьте, может ли он быть брошен.
if (readData is T) { return (T)readData; } try { return (T)Convert.ChangeType(readData, typeof(T)); } catch (InvalidCastException) { return default(T); }
ты пробовал преобразовать.Тип изменения?
Если метод всегда возвращает строку, которую я нахожу странной, но это помимо точки, то, возможно, этот измененный код будет делать то, что вы хотите:
private static T ReadData<T>(XmlReader reader, string value) { reader.MoveToAttribute(value); object readData = reader.ReadContentAsObject(); return (T)Convert.ChangeType(readData, typeof(T)); }
вы можете потребовать, чтобы тип был ссылочным типом:
private static T ReadData<T>(XmlReader reader, string value) where T : class { reader.MoveToAttribute(value); object readData = reader.ReadContentAsObject(); return (T)readData; }а затем сделать другой, который использует типы значений и TryParse...
private static T ReadDataV<T>(XmlReader reader, string value) where T : struct { reader.MoveToAttribute(value); object readData = reader.ReadContentAsObject(); int outInt; if(int.TryParse(readData, out outInt)) return outInt //... }
вы можете предположительно передать в качестве параметра делегат, который преобразуется из string в T.
на самом деле, проблема здесь заключается в использовании ReadContentAsObject. К сожалению, этот метод не соответствует его ожиданиям; хотя он должен определить наиболее подходящий тип для значения, он фактически возвращает строку, независимо от того, что(это можно проверить с помощью Reflector).
однако, в вашем конкретном случае, вы уже знаете, тип, который вы хотите бросить в, Поэтому я бы сказал, что вы используете неправильный метод.
попробуйте использовать ReadContentAs вместо этого, это точно Что вам нужно.
private static T ReadData<T>(XmlReader reader, string value) { reader.MoveToAttribute(value); object readData = reader.ReadContentAs(typeof(T), null); return (T)readData; }
добавить ограничение' class ' (или более подробно, как базовый класс или интерфейс ваших exepected t объектов):
private static T ReadData<T>(XmlReader reader, string value) where T : class { reader.MoveToAttribute(value); object readData = reader.ReadContentAsObject(); return (T)readData; }или
where T : IMyInterfaceилиwhere T : new(), etc
на самом деле, ответы вызывают интересный вопрос, который вы хотите, чтобы ваша функция делала в случае ошибки.
может быть, было бы более разумно построить его в виде метода TryParse, который пытается читать в T, но возвращает false, если это невозможно сделать?
private static bool ReadData<T>(XmlReader reader, string value, out T data) { bool result = false; try { reader.MoveToAttribute(value); object readData = reader.ReadContentAsObject(); data = readData as T; if (data == null) { // see if we can convert to the requested type data = (T)Convert.ChangeType(readData, typeof(T)); } result = (data != null); } catch (InvalidCastException) { } catch (Exception ex) { // add in any other exception handling here, invalid xml or whatnot } // make sure data is set to a default value data = (result) ? data : default(T); return result; }редактировать: теперь, когда я думаю об этом, мне действительно нужно сделать преобразование.тест типа изменений? разве линия as уже не пытается это сделать? Я не уверен, что дополнительные вызов changetype фактически выполняет все. На самом деле, это может только увеличить нагрузку, генерируя исключение. Если кто-нибудь знает о разнице, что делает его стоит сделать, пожалуйста, напишите!
Comments