0

У меня есть ряд классов, которые я хочу сериализовать и де-сериализовать. Я пытаюсь создать функцию, которая с учетом типа («Пользователь», «Администратор», «Статья» и т. Д.) Де-сериализует файл со списком этих элементов. Например:Данная System.Type T, Deserialize List <T>

/* I want to be able to do this */ 
List<Article> allArticles = GetAllItems(typeof(Article)); 

Я не могу понять, как достичь выше, но мне удалось получить эту работу:

/* BAD: clumsy method - have to pass a (typeof(List<Article>)) 
    instead of typeof(Article) */ 
List<Article> allArticles = (List<Article>)GetAllItems(typeof(List<Article>)); 

/* Then later in the code... */ 
public static IList GetAllItems(System.Type T) 
{ 

    XmlSerializer deSerializer = new XmlSerializer(T); 

    TextReader tr = new StreamReader(GetPathBasedOnType(T)); 
    IList items = (IList) deSerializer.Deserialize(tr); 
    tr.Close(); 

    return items; 
} 

Проблема заключается в том, что я должен пройти «некрасиво» typeof(List<Article>) вместо " симпатичный "typeof(Article).

Когда я пытаюсь это:

List<User> people = (List<User>)MasterContactLists.GetAllItems(typeof(User)); 

/* Followed by later in the code...*/ 
public static IList GetAllItems(System.Type T) 
{ 
    XmlSerializer deSerializer = new XmlSerializer(typeof(List<T>)); 

    TextReader tr = new StreamReader(GetPathBasedOnType(T)); 
    IList items = (IList)deSerializer.Deserialize(tr); 
    tr.Close(); 

    return items; 
} 

... Я получаю сообщение об ошибке

/*Error 3 
The type or namespace name 'T' could not be found 
(are you missing a using directive or an assembly reference?) 
on this line: ... = new XmlSerializer(typeof(List<T>)); */ 

Вопрос: как я могу исправить мой GetAllItems(), чтобы иметь возможность вызвать функцию, как это и есть его вернуть список:

List<Article> allArticles = GetAllItems(typeof(Article)); 

Спасибо!

ответ

3

Ты почти там ... вам нужно объявить общий метод:

public static IList<T> GetAllItems<T>() 
{ 
    XmlSerializer deSerializer = new XmlSerializer(typeof(List<T>)); 

    using(TextReader tr = new StreamReader(GetPathBasedOnType(typeof(T)))) 
    { 
     IList<T> items = (IList<T>)deSerializer.Deserialize(tr); 
    } 

    return items; 
} 
+0

Спасибо, Томас! И если я хочу кэшировать элементы, я бы использовал ... Cache ["asset" + typeof (T) .ToString()] = items; ... правый? –

+0

Я думаю, вы могли бы это сделать, но я не очень хорошо знаком с ASP.NET ... –

+0

Спасибо, Томас. Это действительно полезно. Хотя похоже, что изменение объявления функции/прототипа требует перезаписи тонны зависимого кода. Есть ли более простой способ в функции с объявлением GetAllItems (System.Type T) для создания сериализатора ** LIST ** этих элементов - например: new XmlSerializer (typeof (List )); "? –