2007/12/13(Thu) 18:56:40 編集(投稿者)
2007/12/13(Thu) 18:55:43 編集(投稿者)
■No11439 (囚人 さん) に返信
> コレクションの型が分からない、コレクションの要素の型も分からない、コレクションの要素がシールドであるという前提
> という条件で、コレクションの要素をインスタンス化できてもいいんじゃないかと。
ご質問の内容を恐らくほとんど理解できていないのですが,
あるインスタンス o が IEnumerable<T> を実装しているとき,
その T を得るのは以下のコードで可能です.
public static Type GetCollectionTypeFromInstance(object o)
{
Type instType = o.GetType();
var enumrableTypes = from i in instType.GetInterfaces()
where i.IsGenericType
where i.GetGenericTypeDefinition() == typeof(IEnumerable<>)
select i.GetGenericArguments()[0];
return enumrableTypes.Single();
}
が,この方法には問題もあります.
1) GetInterfaces はその型が実装する全てのインターフェイスを返すわけではない
(暗黙に実装されるインターフェイスが存在する)
2) あるインスタンス o は,IEnumerable<T1> と IEnumerable<T2> というように
複数の IEnumerable<> を実装しているかもしれない
例)
object array = Enum.GetValues(typeof(DayOfWeek)) as DayOfWeek[];
var interfaces = array.GetType().GetInterfaces();
var a = array is IEnumerable<int>; // true
var b = array is IEnumerable<DayOfWeek>; // true
var ia = interfaces.Contains(typeof(IEnumerable<int>)); //false
var ib = interfaces.Contains(typeof(IEnumerable<DayOfWeek>)); //true
DayOfWeek[] 型に対する GetInterfaces() は IEnumerable<int> を含みませんが,
実際には DayOfWeek[] 型のインスタンスは IEnumerable<int> を実装しています.
囚人さんはどうも汎用的な何かのコードを書こうとされているようですが,
何となくの印象としては,
条件が不足していて実装がひとつに定まらない問題になってしまっている気がします.
まあ上のコードが何かの参考になりましたら幸いです.