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

时间:2015-02-25 22:34:37

标签: c# generic-collections

我想编写一个带有一个输入参数的函数,然后:

  • 如果它是一个对象列表,那么做一件事,但是
  • 如果是单个对象,则做另一件事。

我想这个功能看起来像这样:

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

由于各种原因,最好在一个函数内完成所有这些。

(我使用的ListSystem.Collections.Generic中的标准版。)

3 个答案:

答案 0 :(得分:3)

所以你需要把它投射到List

不尝试反射为什么不使用函数重载:

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());

答案 1 :(得分:3)

如果这是学术练习,那么您可以滥用运行时类型解析。

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

答案 2 :(得分:1)

您可以使用Reflection来查看它是List<T>

var type = x.GetType();
if(type.IsGenericType &&
   type.GetGenericTypeDefinition() == typeof(List<>))

或者,如果您想知道它是否是一般的集合,您可以尝试检查它是否为IList

if(x is IList)