2013-04-10 11 views
10

voglio passare un array di oggetti personalizzati per una funzione come String.Join che ha le seguenti firme:Passando array funzione che prende sia oggetto params [] o IEnumerable <T>

  • public static string Join(string separator, params Object[] values)
  • public static string Join(string separator, IEnumerable<T> values)

Se io chiamo la funzione come questa:

var arr = new MyClass[]{ new MyClass(), new MyClass() }; 
string text = string.Join("\n", arr); 

ottengo un errore di compilazione:

The call is ambiguous between the following methods or properties: 'string.Join(string, params object[])' and 'string.Join(string, System.Collections.Generic.IEnumerable)'

posso risolvere l'ambiguità utilizzando la funzione IEnumerable<T>:

var arr = new MyClass[]{ new MyClass(), new MyClass() }; 
string text = string.Join<MyClass>("\n", arr); 

Ma posso chiamare la funzione params object[]? In uno scenario di prestazioni critiche, sarebbe preferibile accedere direttamente alla matrice piuttosto che tramite un enumeratore.

Sto usando C# 4.0, se questo fa alcuna differenza.

risposta

17

Se si passa un object[] come secondo parametro, il compilatore deve scegliere il sovraccarico object[] poiché corrisponde esattamente. Nel caso in cui si dispone di un array diverso digitato (MyClass[] in questo caso) solo lanciare l'array object[]:

string.Join("\n", (object[])arr); 

non sono in realtà cambiando il tipo di oggetti o eseguire alcuna conversione in fase di esecuzione, è' sto solo dando al compilatore un suggerimento su quale sovraccarico usare.

E per quanto riguarda il commento sulle prestazioni, non dimenticare di confrontare entrambe le opzioni se le prestazioni sono così importanti. Non dare per scontato che uno sia più veloce dell'altro. (E sempre il profilo l'intera applicazione - è probabile che eventuali colli di bottiglia stanno per essere altrove.)

3

Se si cambia il tipo di variabile arr-object[] si chiamerà l'altro di sovraccarico:

object[] arr = new MyClass[] { new MyClass(), new MyClass() }; 
string text = string.Join("\n", arr); 

Puoi anche scriverlo esplicitamente su object[]: string.Join ("\ n", (oggetto []) arr);

0

È possibile chiamare l'altro di sovraccarico come questo (che è quello che param vengono utilizzati per) -

string text = string.Join("\n", new MyClass(), new MyClass()); 
0

Il cambiamento più semplice per il codice sarebbe quello di andare da:

var arr = new MyClass[]{ new MyClass(), new MyClass() }; 
    string text = string.Join("\n", arr); 

A:

var arr = new object[]{ new MyClass(), new MyClass() }; 
    string text = string.Join("\n", arr); 

Come detto prima, il casting funziona anche:

var arr = new MyClass[]{ new MyClass(), new MyClass() }; 
    string text = string.Join("\n", (object[])arr); 

Per ulteriori informazioni su questo argomento, ricerca C# overload resolution.

La risoluzione del sovraccarico è un argomento interessante di per sé, ma non ho ancora trovato il collo di bottiglia per un problema di prestazioni.

+0

Come ho detto nella mia domanda, voglio passare l'array all'implementazione appropriata della mia funzione (non String.Join, ma qualcosa con firme di metodo simili). La differenza di prestazioni qui è dovuta alle diverse implementazioni della mia funzione. Alcune operazioni, come ottenere il numero di elementi nella raccolta, vengono eseguite più velocemente utilizzando una matrice piuttosto che un 'IEnumerable '. – bouvierr

+0

Il metodo di estensione Count() utilizza la proprietà .Length nel caso in cui l'oggetto IEnumerable sia un array, ma non è questo il punto. Potresti considerare di utilizzare nomi diversi per i membri e non fare affidamento sulla risoluzione di sovraccarico, se la differenza di prestazioni è così importante. Pertanto, non dovrai forzare i tipi in fase di compilazione per ottenere la semantica che stai cercando. – Doug

0

Se usate IEnumerable è possibile utilizzare il <object> overload generica del metodo ToArray():

var allFoos = foo.GetAllFoos().ToArray<object>(); 
string s = string.Join(", ", allFoos); 

sembra meno gonfio e più leggibile per me.

Problemi correlati