对对象做一件事,对对象列表做另一件事



我想写一个接受一个输入参数的函数,然后:

  • 如果它是一个对象列表,则执行一件事,但是
  • 如果是单个对象,则执行另一件事。

我想象这个函数看起来像这样:

 void DoSomething(object x) {
      if (x is List) { Swizzle(x); }
      else { Wibble(x); }
 }

出于各种原因,最好在单个函数中完成所有这些操作。

(我正在使用的ListSystem.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)

最新更新