2010-09-06 5 views
3

Je voudrais convertir T en T [] s'il s'agit d'un tableau.C#: Convertir T en T []

static T GenericFunction<T>(T t) 
{ 
     if (t == null) return default(T); 

     if (t.GetType().IsArray) 
     { 
      //if object is an array it should be handled 
      //by an array method 
      return (T) GenericArrayFunction((T[])t); 
     } 
     ... 
} 

static T[] GenericArrayFunction<T>(T[] t) 
{ 
     if (t == null) return default(T); 

     for (int i = 0 ; i < t.Length ; i++) 
     { 
      //for each element in array carry 
      //out Generic Function 
      if (t[i].GetType().IsArray()) 
      { 
       newList[i] = GenericArrayFunction((T[])t[i]); 
      } 
      else 
      { 
       newList[i] = GenericFunction(t[i]); 
      } 
     } 
     ... 
} 

Erreur Si je tente (T []) t

Impossible de convertir le type 'T' 'T []'

Erreur Si je viens essayer à transmettre t

Les arguments de type pour la méthode 'GenericAr rayFunction (T []) 'ne peut pas être déduit de l'utilisation. Essayez de spécifier explicitement les arguments de type.

+1

Veuillez fournir le contexte. –

+3

Si 'T' est un tableau,' T [] 'est un tableau de tableaux. Ce n'est probablement pas ce que vous attendiez. – Gabe

+2

Si 'T' est un tableau alors' T [] 'est un tableau de tableaux. Je doute que ce soit ce que tu veux. Voulez-vous dire que si T est un tableau de type U d'un type inconnu, alors vous voulez le type "array of U", 'U []'? – jalf

Répondre

2

Tout simplement parce que T est un type de tableau ne veut pas dire qu'il est aussi un tableau deT. En fait, la seule façon qui pourrait arriver serait que T soit quelque chose comme object, Array ou l'une des interfaces implémentées par les tableaux.

Qu'essayez-vous vraiment de faire? Je soupçonne que vous voulez trouver le type d'élément de la matrice, puis appelez GenericArrayFunction avec le T approprié - mais ce ne sera pas le mêmeT, et vous aurez besoin de l'appeler avec la réflexion, ce qui sera un peu douloureux. (. Pas trop mal, mais désagréable)

Je suspect-vous pas bien comprendre C#/génériques NET -. S'il vous plaît nous donner plus de contexte sur l'image plus grande afin que nous puissions vous aider à mieux.

EDIT: L'approche de réflexion serait quelque chose comme ceci:

private static readonly ArrayMethod = typeof(NameOfContainingType) 
    .GetMethod("GenericArrayFunction", BindingFlags.Static | BindingFlags.NonPublic); 

... 

static T GenericFunction<T>(T t) 
{ 
     if (t == null) return default(T); 

     if (t is Array) 
     { 
      Type elementType = t.GetType().GetElementType(); 
      MethodInfo method = ArrayMethod.MakeGenericMethod(new[] elementType); 
      return (T) method.Invoke(null, new object[] { t }); 
     } 
     ... 
} 

Notez que cela échouera encore pour les tableaux rectangulaires, qui deviennent encore plus difficiles à faire face.

+0

J'essaie de transmettre T à la fonction GenericArrayFunction. Pouvez-vous s'il vous plaît expliquer comment l'appeler avec réflexion? –

+0

J'aimerais pouvoir transmettre des arguments lors de l'exécution. Si l'argument est un tableau, je voudrais effectuer des opérations sur les tableaux, sinon, mener l'opération par défaut. –

+0

@Shiftbit: Vous devez donner plus d'informations que cela en termes de ce que vous essayez vraiment de faire. –

2

Ce n'est pas possible. T ne peut jamais être T[]. T est toujours un certain type, pas seulement un espace réservé. Si T est array (int[]), alors T[] sera int[][].

Modifier: Il y a quelques exceptions (comme object est object[]), mais dans le cas général (et c'est ce que les génériques sont) T ne peut pas être T []

+0

'object []' est un 'object'. Vous pouvez donc appeler 'GenericFunction (nouvel objet [5])'. Mais oui, c'est peu probable. –

+0

@Jon Skeet je l'ai compris quand j'ai vu votre réponse :) mais dans le cas général (et c'est ce que génériques sont) T ne peut pas être T [] – Andrey

+0

Sur une note connexe, il serait possible pour T de fournir implicitement l'opérateur de conversion en 'T []', bien que cela ne puisse pas être exprimé avec une contrainte générique. Cependant, il serait possible d'écrire 'class Foo: IEnumerable ' et d'exprimer 'où T: IEnumerable ' dans une contrainte séparée qui accepterait alors 'Foo'. – Ani

4

A en juger par votre exemple particulier, pourriez-vous ne pas définir deux méthodes et laisser le compilateur choisir le bon quand un tableau est passé?

using System; 

class Program 
{ 
    static T GenericFunction<T>(T t) 
    { 
     Console.WriteLine("GenericFunction<T>(T)"); 
     return default(T); 
    } 

    static T[] GenericFunction<T>(T[] t) 
    { 
     // Call the non-array function 
     for(int i = 0; i < t.Length; ++i) 
      t[i] = GenericFunction(t[i]); 

     Console.WriteLine("GenericFunction<T>(T[])"); 
     return new T[4]; 
    } 

    static void Main() 
    { 
     int[] arr = {1,2,3}; 
     int i = 42; 

     GenericFunction(i); // Calls non-array version 
     GenericFunction(arr); // Calls array version 
    } 
} 
+1

À moins que l'OP n'explique pas une complexité cachée ... ce serait juste dandy. – Rusty

+1

+1 Solution très simple. –

+0

Le problème avec ceci est si je passe dans int [] i = {...}, objet o = i. Fonction générique (o). Il ne va pas à la fonction de tableau appropriée. –

Questions connexes