2012-05-24 10 views
38

Sto provando a convertire un oggetto (è dichiarato qui come 'obj': object is array, primitive) in una stringa array.object to string array

oggetto può essere qualsiasi cosa uint [], Int16 [], ecc

Ho cercato di utilizzare

string[] str = Array.ConvertAll<object, string>((object[])obj, Convert.ToString); 

Il problema si verifica quando si tenta di eseguire il cast dell'oggetto tipo sconosciuto in oggetto [ ]. Ho ricevuto un errore di trasmissione.

Un tentativo che ho fatto, che non è riuscito, stava usando

object[] arr = (object[])obj; 

o

IEnumerable<object> list = obj as IEnumerable<object> 
object[] arr = (object[])list; 

Ho visto le registrazioni per quanto riguarda il tipo di valore e al tipo di riferimento problema sul casting.

Esiste un semplice codice che può gestire il casting su oggetto [] indipendentemente dal tipo di oggetto, purché sia ​​un array? Sto cercando di evitare la gestione manuale di ogni tipo possibile di casting.

grazie in anticipo

+1

non si può lanciare array di tipi di valore per 'oggetto []', non sono compatibili. –

risposta

62

È possibile utilizzare il fatto che ogni matrice implementa IEnumerable:

string[] arr = ((IEnumerable)obj).Cast<object>() 
           .Select(x => x.ToString()) 
           .ToArray(); 

Questo sarà casella primitive in modo appropriato, prima di convertirli in stringhe.

La ragione cast non è che, sebbene array di riferimento tipi sono covariante array di valore tipi non sono:

object[] x = new string[10]; // Fine 
object[] y = new int[10]; // Fails 

Trasmissione a solo IEnumerable funziona però. Diamine, puoi trasmettere a Array se lo desideri.

+0

Perché c'è bisogno di inscatolare le primitive? – Douglas

+0

@Douglas: Poiché non è possibile eseguire il cast di una matrice di tipo primitiva a 'object []', e non conosciamo il tipo in anticipo. –

+0

Funziona anche senza cast per 'IEnumerable', perché vuoi lanciarlo esplicity? – Tigran

10

Se è sempre una raccolta di un certo tipo (array, list, ecc ...) quindi provare di nuovo a lanciare pianura vecchio System.Collections.IEnumerable e passare da lì

string[] str = ((System.Collections.IEnumerable)obj) 
    .Cast<object>() 
    .Select(x => x.ToString()) 
    .ToArray(); 

Ecco un'implementazione più completa che gestisce non -collections così

static string[] ToStringArray(object arg) { 
    var collection = arg as System.Collections.IEnumerable; 
    if (collection != null) { 
    return collection 
     .Cast<object>() 
     .Select(x => x.ToString()) 
     .ToArray(); 
    } 

    if (arg == null) { 
    return new string[] { }; 
    } 

    return new string[] { arg.ToString() }; 
} 
+0

grazie, funziona benissimo –

-1

il mio esempio:

public class TestObject 
    { 
     public string Property1 { get; set; } 

     public string Property2 { get; set; } 

     public string Property3 { get; set; } 
    } 



    static void Main(string[] args) 
    { 
     List<TestObject> testObjectList = new List<TestObject> 
     { 
      new TestObject() { Property1 = "1", Property2 = "2", Property3 = "3" }, 
      new TestObject() { Property1 = "1", Property2 = "2", Property3 = "3" }, 
      new TestObject() { Property1 = "1", Property2 = "2", Property3 = "3" } 
     }; 

     List<string[]> convertedTestObjectList = testObjectList.Select(x => new string[] { x.Property1, x.Property2, x.Property3 }).ToList(); 
    }