基于数组参数类型调度递归泛型函数调用

时间:2011-12-14 16:42:11

标签: c#

根据参数是一个任意深度的数组,还是非数组(值),编写一个给定类型的函数表现不同的函数。对于数组类型,重载会迭代数组并进行递归。

我希望递归调用数组参数重载,以便对子数组进行递归调用。但是,递归调用直接转到值类型重载。我宁愿避免使用基于运行时的功能,例如内省。

使用Visual Studio 2010 .Net 4虽然也想支持.Net 3.5。

namespace Quickie.StackOverflow.GenericMethodDispatch
{
    class TestGenericMethodDispatch
    {
        static private void GenericDereferenceArray<T>(T t)
        {
            Console.WriteLine(string.Format("GenericDereferenceArray<T>(T t) got a {0} which thinks it's a {1}, {2}", typeof(T), t.GetType(), t));
        }

        static private void GenericDereferenceArray<T>(T[] t)
        {
            Console.WriteLine(string.Format("GenericDereferenceArray<T>(T[] t) got a {0} which thinks it's a {1}", typeof(T[]), t.GetType()));
            foreach (T iter in t)
            {
                GenericDereferenceArray(iter);
            }
        }

        static public void TestGenericDereferenceArray()
        {
            Console.WriteLine();
            Console.WriteLine("===TestGenericDereferenceArray()===");

            Console.WriteLine("====Dereference an int====");
            int i = 1;
            GenericDereferenceArray(i);
            Console.WriteLine();

            Console.WriteLine("====Dereference an int[]====");
            int[] ai = { 1 };
            GenericDereferenceArray(ai);
            Console.WriteLine();

            Console.WriteLine("====Dereference an int[][]====");
            int[][] aai = { new int[] { 2 } };
            GenericDereferenceArray(aai);
            Console.WriteLine();
        }
    } // Ends class TestGenericMethodDispatch
} // Ends namespace Quickie.StackOverflow.GenericMethodDispatch

输出:

  

=== TestGenericDereferenceArray()===
  ====取消引用字符串====
  GenericDereferenceArray(T t)得到一个System.String认为它是一个System.String,foo

     

====取消引用int ====
  GenericDereferenceArray(T t)得到一个System.Int32认为它是System.Int32,1

     

====取消引用int [] ====
  GenericDereferenceArray(T [] t)得到一个System.Int32 [],认为它是System.Int32 []
  GenericDereferenceArray(T t)得到一个System.Int32认为它是System.Int32,1

     

====取消引用int [] [] ====
  GenericDereferenceArray(T [] t)得到一个System.Int32 [] [],认为它是System.Int32 [] []
  GenericDereferenceArray(T t)得到一个System.Int32 [],认为它是System.Int32 [],System.Int32 []

希望后者的输出是

  

====取消引用int [] [] ====
  GenericDereferenceArray(T [] t)得到一个System.Int32 [] [],认为它是System.Int32 [] []
  GenericDereferenceArray(T [] t)得到一个System.Int32 [],认为它是System.Int32 []
  GenericDereferenceArray(T t)有一个System.Int32认为它是System.Int32,System.Int32

2 个答案:

答案 0 :(得分:0)

因为GenericDereferenceArray(iter)会调用GenericDereferenceArray<T>(T t),即使它是一个数组。您可以检查一个数组(或IEnumerable中的更通用的GenericDereferenceArray<T>(T t)

    static private void GenericDereferenceArray<T>(T t)
    {
        Console.WriteLine(string.Format("GenericDereferenceArray<T>(T t) got a {0} which thinks it's a {1}, {2}", typeof(T), t.GetType(), t));
        if (t is IEnumerable)
            foreach (var t2 in (IEnumerable)t)
            {
                GenericDereferenceArray(t2);
            }
    }

答案 1 :(得分:0)

当您将int[][]作为参数传递给期望T[]的方法时,会使T的类型为int[],这是您在输出中看到的。为了使其行为符合您的要求,您必须在方法中对此情况进行特殊处理。

或者,为T[][]添加另一个重载。