2009-12-16 7 views
8

Poniższa funkcja akceptuje obiekt, który czasami może być tablicą danego typu. W tym przypadku, przypuszczam, że typ można określić za pomocą obj [0] .GetType(), zakładając, że tablica ma co najmniej jeden element. Chciałbym przekonwertować taką tablicę na typowy List odpowiedniego typu, ale poniższy kod tylko konwertuje na obiekt <. Jak to zrobić?Konwertuj tablicę dowolnego typu na listę <T> (C#)

 
     public object GetDeserializedObject(object obj, Type targetType) 
     { 
      if (obj is Array) 
      { 
       List<object> obj2 = new List<object>(); 
       for (int i = 0; i < ((Array)obj).Length; i++) 
       { 
        obj2.Add(((object[])obj)[i]); 
       } 
       obj = obj2; 
      } 
      return obj; 
     } 

Zauważ, że GetSerializedObject() realizuje funkcję należącej do interfejsu IDataContractSurrogate, więc nie sądzę, mogę zmienić swój podpis, jak pokazano.

Odpowiedz

16

Zakładając, nie wiesz, typ w czasie kompilacji, ty” Chcę stworzyć ogólną metodę, aby to zrobić, a następnie nazwać to przez odbicie. Na przykład:

private static List<T> ConvertArray<T>(Array input) 
{ 
    return input.Cast<T>().ToList(); // Using LINQ for simplicity 
} 

public static object GetDeserializedObject(object obj, Type targetType) 
{ 
    if (obj is Array) 
    { 
     MethodInfo convertMethod = typeof(...).GetMethod("ConvertArray", 
      BindingFlags.NonPublic | BindingFlags.Static); 
     MethodInfo generic = convertMethod.MakeGenericMethod(new[] {targetType}); 
     return generic.Invoke(null, new object[] { obj }); 
    } 
    return obj; 
} 

(Jeśli zrobić znać typ w czasie kompilacji, po prostu zrobić to sposób ogólny i nazywają Cast i ToList bezpośrednio.)

+2

Co należy w miejscu "..."? –

+1

@nw: Klasa, w której umieścisz metodę 'ConvertArray' zdefiniowaną przez Jona. To znaczy, jeśli umieścisz metodę' ConvertArray' w klasie o nazwie 'ArrayConverter', a następnie zastąp' '...' 'ArrayConverter'. – jason

+1

@ Jon: "TargetType" powinno być "Type". – jason

3

Spróbuj odlewany() metoda LINQ:

public object GetDeserializedObject<T>(object obj) 
    { 
     if (obj is Array) 
     { 
      var list = ((Array)obj).Cast<T>().ToList(); 
      obj = list; 
     } 
     return obj; 
    } 

A ty określić typ chcesz w T.

+1

miałem zamiar iść zupełnie inny kierunek , ale jest to o wiele bardziej eleganckie. – rossipedia

+2

GetSerializedObject() implementuje funkcję należącą do interfejsu IDataContractSurrogate, więc nie sądzę, żebym mógł zmienić jej sygnaturę, tak jak pokazano. –

Powiązane problemy