2011-12-14 72 views
0

根据参数是任意深度的数组还是非数组(值),编写对于给定类型行为不同的函数。对于数组类型,重载遍历数组并递归。我想递归调用数组参数重载递归调用子数组。然而,递归调用直接进入值类型重载。我宁愿避免基于运行时的功能,如自省。基于数组参数类型的调度递归泛型函数调用

使用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,System.Int32

回答

0

因为GenericDereferenceArray(iter)调用GenericDereferenceArray<T>(T t)即使它是一个数组。你可以检查一个数组(或更一般的IEnumerableGenericDereferenceArray<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); 
      } 
    } 
+0

很明显,从输出中调用“GenericDereferenceArray (T t)”。这并不能帮助我理解为什么,或者是否有解决方法,不需要这种类型的投射。投射到你知道的东西是有效的,对我来说是错误的。将T [] []数组的元素投射到T []或IEnumerable 似乎是多余的。 – WaffleSouffle 2011-12-14 17:21:56

+0

因为当你调用`GenericDereferenceArray(iter)`时,你传递的是对象而不是_explicit_对象数组。尽管_technically_是一个数组,编译器会将它连接到T版本。 – 2011-12-16 21:34:54

0

当你传递一个int[][]作为参数传递给需要T[]的方法,使Tint[]类型,这是你所看到的为了使其表现得像你想要的那样,你必须在你的方法中对这种情况进行特殊处理。

或者,为T[][]增加另一个过载。