【发布时间】:2015-02-07 07:06:06
【问题描述】:
鉴于下面的示例代码,我想在泛型方法(在本例中为retrieveData)中获取 T 的运行时类型。当我创建 XMLFilePersisting 时,我使用接口,即 ITransferable 而不是实现类型,因为在我的客户端中,我希望将所有这些类型放在一起:
List<XMLFilePersisting<ITransferable>> allThem;
因此,如果在retrieveData 我执行 typeof(T) 应该返回 ITransferable ,它没有给我足够的信息来从文件中加载项目。我能弄清楚如何做到这一点的唯一方法是在构造函数中传递 ITransferable 的实现者的实例,但这种感觉应该有更好的方法。有什么建议吗?
public interface IPersisting<T> {
List<T> retrieveData();
bool persistData(List<T> lst);
}
public interface ITransferable {
Type getRuntimeType();
}
public class XMLFilePersisting<T> : IPersisting<T> where T : ITransferable {
private readonly T defaultT;
//...
public XMLFilePersisting(string thefile, string thepath, T def) {
//...
defaultT = def;
}
...
public List<T> retrieveData() {
List<T> retVal = new List<T>();
Type runType = defaultT.getRuntimeType();
string elemName = runType.Name;
using (FileStream fs = new FileStream(FQ_FILE_PATH, FileMode.Open, FileAccess.Read)) {
using (XmlReader reader = XmlReader.Create(fs)) {
//below line won't work, typeof resolves at compileTime
//XmlSerializer xmlSer = new XmlSerializer(typeof(T));
XmlSerializer xmlSer = new XmlSerializer(runType);
if (reader.ReadToFollowing(elemName)) { //go to the first test, skipping over ListofT
do {
T testVal = (T)xmlSer.Deserialize(reader);
retVal.Add(testVal);
}
while (reader.ReadToNextSibling(elemName));
}
} //end using xmlreader
} //end using FileStream
return retVal;
} //end retrieveData
} //end class XMLFilePersisting
附加信息:
客户端代码如下所示。如您所见,我需要所有的
IPersisting<ITransferable>
实例,但问题在于retrieveData,这使得typeof(T) = ITransferable 没有给我足够的信息来进行反序列化。这就是为什么我将 ITransferable 的具体实现传递给构造函数(MyClass1,MyClass2)。这似乎行得通,但感觉就像一个 hack。
IPersisting<ITransferable> xfpMC1 = new XMLFilePersisting<ITransferable>("persistedMC1.xml", myTempDirectory, new MyClass1());
IPersisting<ITransferable> xfpMC2 = new XMLFilePersisting<ITransferable>("persistedMC2.xml", myTempDirectory, new MyClass2());
一个
【问题讨论】:
-
首先要改变:开始遵循 .NET 命名约定。如果您满足他们的命名期望,它会让其他人更容易阅读您的代码。
-
接下来,您将在哪里传递有关您想要的实际类型的信息完全不清楚。您的“当我创建 XMLFilePersisting 时,我使用接口,即 ITransferable 而不是实现类型,因为在我的客户端中,我希望将所有这些类型放在一起”并没有对我解释太多。您是否正在创建
XMLFilePersisting的多个实例?如果是这样,为什么不为每个具体类型创建一个实例,然后从结果中构建一个大的List<ITransferable>? -
对不起。我编辑了我的问题,以更好地显示我的调用代码中的相关部分
-
好吧,我们仍然不知道您为什么希望他们成为
IPersisting<ITransferable>而不是IPersisting<MyClass1>和IPersisting<MyClass2>,这显然可以解决问题。 -
@JonSkeet 在一天结束时,我希望他们都进入一个强类型列表