Используйте параметр System.Type T в списке <T> - PullRequest
0 голосов
/ 09 ноября 2010

Предположим, у меня есть функция:

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; 
} 

Чтобы получить список статей, я хотел бы позвонить GetAllItems(typeof(Article)) вместо GetAllItems(typeof(List<Article>)), но все равно вернуть список.

Вопрос : как мне, , не изменяя объявление функции / прототип , не требовать ненужной части List<> при вызове этой функции?

То есть яищу что-то вроде этого:

public static IList GetAllItems(System.Type T) 
{ 
    /* DOES NOT WORK:  Note new List<T> that I want to have */     
    XmlSerializer deSerializer = new XmlSerializer(List<T>); 

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

    return items; 
} 

Ответы [ 2 ]

0 голосов
/ 09 ноября 2010

Вы вызываете GetAllItems (typeof (Article)), поэтому я предполагаю, что вы знаете тип статически. Если это действительно так, то как насчет:

public static IList<T> GetAllItems<T>() //Note T is now a type agrument
{
    //the using statement is better practice than manual Close()
    using (var tr = new StreamReader(GetPathBasedOnType(typeof(T)))) 
       return (List<T>)new XmlSerializer(typeof(List<T>)).Deserialize(tr);
}

Вы бы сейчас позвонили GetAllItems<Article>().

Также рассмотрите возможность использования DataContractSerializer вместо XmlSerializer .

0 голосов
/ 09 ноября 2010

Если я вас правильно понял, у вас есть сериализованный список в потоке, да? Если так, то просто измените это во втором примере:

XmlSerializer deSerializer = new XmlSerializer(List<T>);

Примерно так:

if (!T.IsGenericType || T.GetGenericTypeDefinition() != typeof(List<>))
    T = typeof(List<>).MakeGenericType(new Type[] { T });

XmlSerializer deSerializer = new XmlSerializer(T);

Это проверит тип, переданный в; если это List<T>, то он будет использоваться без изменений. В противном случае вместо него будет использоваться соответствующий тип List<T>.

Другими словами, если вы передадите typeof(Foo), тогда T станет List<Foo>. Но если вы введете typeof(List<Foo>), то T останется List<Foo>.

...