のようなものはありません、これを行うには組み込みのメカニズムはありません。いくつかを組み合わせることができますreflection APIs。
まず、GetType()と、コレクション内の各オブジェクトのための本当の種類を取得することができます。
IEnumerable<Type> realTypes = hs.Select(o => o.GetType());
今、あなたはBaseType財産とGetInterfaces()方法を持っているTypeクラスのコレクションを持っています。 Ypuは、各タイプのすべての階層を取得するためにthis codeを使用することができます。
public static IEnumerable<Type> GetParentTypes(this Type type)
{
// is there any base type?
if ((type == null) || (type.BaseType == null))
{
yield break;
}
// return all implemented or inherited interfaces
foreach (var i in type.GetInterfaces())
{
yield return i;
}
// return all inherited types
var currentBaseType = type.BaseType;
while (currentBaseType != null)
{
yield return currentBaseType;
currentBaseType= currentBaseType.BaseType;
}
}
あなたは階層のコレクションを取得するためにそれを使用することができます:
IEnumerable<IEnumerable<Type>> baseTypes = realTypes.Select(t => t.GetParentTypes());
次のステップは、唯一の交差の値を持つように、すべてのこのリストをマージすることです。あなたはEnumerable.Intersect方法とthisコードでそれを行うことができます。
public static IEnumerable<T> IntersectAllIfEmpty<T>(params IEnumerable<T>[] lists)
{
IEnumerable<T> results = null;
lists = lists.Where(l => l.Any()).ToArray();
if (lists.Length > 0)
{
results = lists[0];
for (int i = 1; i < lists.Length; i++)
results = results.Intersect(lists[i]);
}
else
{
results = new T[0];
}
return results;
}
は最後に、我々は持っている:
IEnumerable<Type> realTypes = hs.Select(o => o.GetType());
IEnumerable<IEnumerable<Type>> baseTypes = realTypes.Select(t => t.GetParentTypes());
IEnumerable<Type> inersectedBaseTypes = IntersectAllIfEmpty(baseTypes);
その後、我々は、各タイプを反復し、それらの1つを確実にするためにType.IsAssignableFrom()メソッドを使用することができます
Type mostConcreteType = inersectedBaseTypes.Where(t => inersectedBaseTypes.Count(bt => t.IsAssignableFrom(bt)) == 1).FirstOrDefault();
いいえありません。 –
代わりに、コードをリファクタリングする必要があります。なぜあなたは知らない同じコレクションにオブジェクトを保存しますか? –
@TimSchmelterそれは私のコレクションではありません。 (具体的には、DataGridのItemsSourceで、実行時に実行時に「述語」を一般的な方法で作成したいと思っています。) –