私はこのようなことをしたいです
void DoSomething<T>(T param)
{
if param is IEnumerable<?>
{
loop param and do stuff
}
}
クエスチョンマークのところはどうすればいいのかわかりません。そして、それはまったく可能ですか?
あなたが探しているのは:
if (T is IEnumerable) { .. }
しかし、T が常に IEnumerable であると予想される場合は、次のように実行できます。
void DoSomething<T>(T param) where T : IEnumerable
{
foreach (var t in param) { ... }
}
または IEnumerable 内の値の型を確認します。
public void DoSomething<T,U>(T val) where T : IEnumerable<U>
{
foreach (U a in val)
{
}
}
自分でチェックすることを心配することなく、コンパイラーがそれを行います。これは、静的型システムとコンパイラーを持つことの良い点の 1 つです :)
いくつかの方法があります:
void DoSomething<T>(T param)
{
if (param is IEnumerable)
{
foreach (var item in (IEnumerable)param)
{
// Do something
}
}
}
void DoSomething<T>(T param)
{
if (param is IEnumerable<string>)
{
foreach (var item in (IEnumerable<string>)param)
{
// Do something
}
}
}
void DoSomething<T,TItem>(T param)
{
if (param is IEnumerable<TItem>)
{
foreach (var item in (IEnumerable<TItem>)param)
{
// Do something
}
}
}
次のように、クラスが実装する各インターフェイスのオープン ジェネリック型を確認する必要があります。
bool implements = typeof(T).GetInterfaces().Where(t => t.IsGenericType &&
t.GetGenericTypeDefinition() == typeof(IEnumerable<>)).Any();
IEnumerable<T>
これにより、型が何であるかを実際に知らなくても、型が実装されているかどうかを判断できますT
。型はIEnumerable<T>
複数回実装できることに注意してください。
の型パラメーターである型のシーケンスが必要な場合IEnumerable<T>
は、上記のクエリを次のように変更できます。
IEnumerable<Type> types = typeof(T).GetInterfaces().
Where(t => t.IsGenericType &&
t.GetGenericTypeDefinition() == typeof(IEnumerable<>)).
Select(t => t.GetGenericArguments()[0]);