Учитывая приведенный ниже пример кода, я хотел бы получить тип времени выполнения T внутри общего метода (в данном случае retrieveData). Когда я создаю XMLFilePersisting я использую интерфейс, а именно ITransferable, а не типы исполнителей, так как в моем клиенте я хочу иметь список всех из них вместе:Лучший способ получить время работы Тип T?
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). Кажется, это работает, но кажется, что это взломать.
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» из результатов? –
Извините. Я отредактировал мой вопрос, чтобы лучше показать соответствующую часть из моего кода вызова –