我想写一个接受一个输入参数的函数,然后:
- 如果它是一个对象列表,则执行一件事,但是
- 如果是单个对象,则执行另一件事。
我想象这个函数看起来像这样:
void DoSomething(object x) {
if (x is List) { Swizzle(x); }
else { Wibble(x); }
}
出于各种原因,最好在单个函数中完成所有这些操作。
(我正在使用的List
是System.Collections.Generic
中的标准。
所以你需要把它投射到一个列表
在不尝试反射的情况下,为什么不只使用函数重载:
void DoSomething<T>(List<T> aList)
{
// this is Swizzle
}
void DoSomething(object obj)
{
// this is Wibble
}
如果您在编译时不知道类型,因此函数重载不起作用,则可以使用反射
public class Foo
{
private void Swizzle<T>(List<T> list)
{
Console.WriteLine("Sizzle");
}
private void Wibble(object o)
{
Console.WriteLine("Wibble");
}
public void DoSomething(object o)
{
var ot = o.GetType();
if (ot.IsGenericType && ot.GetGenericTypeDefinition() == typeof(List<>))
{
this.GetType().GetMethod("Swizzle", BindingFlags.NonPublic | BindingFlags.Instance).MakeGenericMethod(ot.GetGenericArguments()[0])
.Invoke(this, new object[] { o });
}
else
this.Wibble(o);
}
}
// Then usage
var foo = new Foo();
foo.DoSomething(new List<int>());
foo.DoSomething(new object());
如果这是一个学术练习,那么你可以滥用运行时类型解析。
void DoSomething(object x)
{
Call((dynamic) x);
}
void Call(IList items)
{
Console.WriteLine("Swizzle");
}
void Call(object item)
{
Console.WriteLine("Wibble");
}
例:
DoSomething(new object[] { }); // Swizzle
DoSomething(new List<object> { }); // Swizzle
DoSomething(new List<int> { }); // Swizzle
DoSomething(1); // Wibble
DoSomething(new object()); // Wibble
您可以使用
Reflection
查看它是否List<T>
var type = x.GetType();
if(type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(List<>))
或者,如果您想知道它是否是一般的集合,您可以尝试检查它是否IList
:
if(x is IList)