0

関数があるとします:

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

2 に答える 2

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>()

また、XmlSerializer ではなく DataContractSerializerの使用を検討してください。

于 2010-11-09T12:11:29.630 に答える
0

私があなたを正しく理解していれば、ストリームにシリアル化されたリストがありますよね? もしそうなら、あなたの2番目の例でこれを変更してください:

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>ます。

于 2010-11-08T23:05:21.213 に答える