简体   繁体   中英

Use a parameter System.Type T in List<T>

Suppose I have a function:

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

In order to retrieve a list of Articles, I would like to call GetAllItems(typeof(Article)) instead of GetAllItems(typeof(List<Article>)) but still return a list.

Question : how can I, without changing the function declaration/prototype , avoid requiring unnecessary List<> portion when calling this function?

That is, I am looking for something like this:

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

If I understand you correctly, you have a serialized List in the stream, yes? If so, then just change this, in your second example:

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

To something like this:

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

XmlSerializer deSerializer = new XmlSerializer(T);

This will examine the type passed in; if it is a List<T> then it will be used unmodified. Otherwise, the appropriate List<T> type will be used instead.

In other words, if you pass in typeof(Foo) then T will become List<Foo> . But if you pass in typeof(List<Foo>) then T will stay List<Foo> .

You're calling GetAllItems(typeof(Article)), so I assume you know the type statically. If that is indeed the case, how about:

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

You'd now call GetAllItems<Article>() .

Also, consider using DataContractSerializer rather than XmlSerializer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM