2010-09-06 4 views
3

Я хотел бы преобразовать T в T [], если это массив.C#: Преобразование T в 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]); 
      } 
     } 
     ... 
} 

Ошибка Если я пытаюсь (T []) т

Невозможно преобразовать тип 'T' для 'T []

Ошибка Если я просто пытаюсь для передачи t

Аргументы типа для метода 'GenericAr rayFunction (T []) не может быть выведено из использования. Попробуйте явно указать аргументы типа.

+1

Просьба представить контекст. –

+3

Если 'T' - массив,' T [] '- массив массивов. Вероятно, это не то, чего вы ожидали. – Gabe

+2

Если 'T' - массив, тогда' T [] '- массив массивов. Я сомневаюсь, что это то, что вы хотите. Вы имеете в виду, что если T - массив некоторого неизвестного элемента типа U, то вы хотите получить тип «массив из U», 'U []'? – jalf

ответ

2

Просто потому, что T является тип массива не означает, что это также массив изT. Фактически, единственный способ, который может произойти, - это T быть чем-то вроде object, Array или одним из интерфейсов, реализованных массивами.

Что вы действительно пытаетесь сделать? Я подозреваю, что вы хотите узнать тип элемента массива, а затем позвонить GenericArrayFunction с соответствующим T - но это не будет тот жеT, и вам нужно будет называть его отражением, которое будет несколько болезненный. (. Не слишком плохо, но неприятно)

Я подозреваемый вы не в полной мере понять, C#/NET генерики. - пожалуйста, дайте нам больше контекста о более широкую картину таким образом мы можем помочь вам лучше.

EDIT: Подход отражения будет что-то вроде этого:

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 }); 
     } 
     ... 
} 

Обратите внимание, что это будет по-прежнему не для прямоугольных массивов, которые получают еще труднее справиться.

+0

Я пытаюсь передать T в GenericArrayFunction. Не могли бы вы объяснить, как назвать это отражением? – 2010-09-06 17:32:42

+0

Я хотел бы иметь возможность передавать аргументы во время выполнения. Если аргумент является массивом, я хотел бы провести операции с массивом, иначе выполните операцию по умолчанию. – 2010-09-06 17:36:14

+0

@Shiftbit: вам нужно предоставить больше информации, чем с точки зрения того, что вы действительно пытаетесь сделать. –

2

Невозможно. T никогда не может быть T[]. T - это всегда определенный тип, а не только заполнитель. Если T является массивом (int[]), то T[] будет int[][].

Edit: Есть некоторые исключения (например, object является object[]), но в общем случае (и то, что генерики) T не может быть T []

+0

'object []' является 'объектом'. Таким образом, вы могли бы назвать «GenericFunction (новый объект [5])'. Но да, это маловероятно. –

+0

@ Jon Skeet Я понял это, когда увидел ваш ответ :), но в общем случае (и это то, что генерики) T не может быть T [] – Andrey

+0

В соответствующей заметке было бы возможно, что 'T' будет предоставлять неявное оператора преобразования в 'T []', хотя это не может быть выражено общим ограничением. Тем не менее, можно было бы написать 'class Foo: IEnumerable ' и выразить 'где T: IEnumerable ' в отдельном ограничении, которое затем примет 'Foo'. – Ani

4

Судя по вашему конкретному примеру, вы могли бы не определить два метода и позволить компилятору выбрать правильный, когда массив передан?

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

Если OP не объясняет какую-то скрытую сложность ... это было бы просто денди. – Rusty

+1

+1 Очень простое решение. – 2010-09-06 20:37:58

+0

Проблема с этим, если я передаю int [] i = {...}, объект o = i. GenericFunction (о). Он не перейдет к правильной функции массива. – 2010-09-06 20:41:40

Смежные вопросы