在List <t> </t>中使用参数System.Type T.

时间:2010-11-08 22:41:35

标签: c# asp.net xml-serialization xml-deserialization generic-list

假设我有一个功能:

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 :(得分:0)

如果我理解正确,你在流中有一个序列化列表,是吗?如果是这样,那么在第二个例子中改变它:

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>

答案 1 :(得分:0)

你正在调用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 rather than XmlSerializer