将对象投射到T

我正在使用.NET中的XmlReader类parsingXML文件,我认为编写一个通用的parsing函数来读取不同的属性是很明智的。 我想出了以下function:

 private static T ReadData<T>(XmlReader reader, string value) { reader.MoveToAttribute(value); object readData = reader.ReadContentAsObject(); return (T)readData; } 

当我意识到,这不完全按照我的计划, 它会抛出一个基本types如intdouble的错误,因为一个强制转换不能从string转换为数字types。 有什么办法让我的function以修改后的forms出现?

首先检查一下是否可以投射。

 if (readData is T) { return (T)readData; } else { try { return (T)Convert.ChangeType(readData, typeof(T)); } catch (InvalidCastException) { return default(T); } } 

你有没有试过Convert.ChangeType ?

如果方法总是返回一个string,我发现这个string很奇怪,但除了这个点之外,也许这个改变的代码会做你想要的:

 private static T ReadData<T>(XmlReader reader, string value) { reader.MoveToAttribute(value); object readData = reader.ReadContentAsObject(); return (T)Convert.ChangeType(readData, typeof(T)); } 

尝试

 if (readData is T) return (T)(object)readData; 

你可以要求这个types是一个引用types:

  private static T ReadData<T>(XmlReader reader, string value) where T : class { reader.MoveToAttribute(value); object readData = reader.ReadContentAsObject(); return (T)readData; } 

然后做另一个使用值types和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。 不幸的是,这种方法没有达到预期。 虽然它应该检测值的最appropiratetypes,它实际上返回一个string,无论是什么(这可以使用reflection器validation)。

然而,在你的具体情况下,你已经知道你想投的types,所以我会说你正在使用错误的方法。

尝试使用ReadContentAs,而这正是你所需要的。

 private static T ReadData<T>(XmlReader reader, string value) { reader.MoveToAttribute(value); object readData = reader.ReadContentAs(typeof(T), null); return (T)readData; } 

添加一个“类”约束(或者更详细的,就像你的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 : IMyInterfacewhere T : new()

实际上,这些回答会带来一个有趣的问题,这就是你希望你的function在错误的情况下做的事情。

也许以TryParse方法的forms构造它会更有意义,它试图读入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; } 

编辑:现在我想到了,我真的需要做convert.changetypetesting吗? 不是已经试图做到这一点? 我不确定做额外的更改types调用实际上可以完成任何事情。 实际上,它可能只是通过生成exception来增加处理开销。 如果有人知道一个值得做的差异,请发表!