2014-11-04 14 views
7

C'è un modo in C# per creare una variabile in linea? Qualcosa di simile a questo:TryParse crea parametri in linea?

int x = int.TryParse("5", out new int intOutParameter) ? intOutParameter : 0; 

non credi che questo è più utile rispetto alla creazione di una variabile al di fuori e poi mai usare di nuovo?

+0

può avvolgere in una chiamata di metodo privato? –

+0

come posso farlo? –

risposta

12

Tale sintassi - chiamate espressioni di dichiarazione - era nella lista delle caratteristiche proposte per la prossima versione di C# (versione 6).

Non sei l'unico a pensare che sia utile. Ad esempio, per effettuare una chiamata completa con TryParse, non c'è bisogno di un'istruzione per dichiarare la variabile.

Tuttavia è has been dropped dal lavoro in corso a C# 6.

Sono sicuro di non essere l'unico a sperare che possa tornare in una versione futura. E 'incluso in C# 7 come una dichiarazione (senza bisogno di new):

int x = int.TryParse("5", out int intOutParameter) ? intOutParameter : 0; 
+1

Posso capire perché l'hanno lasciato cadere per ora però - troppi casi speciali o parsing handwavey necessari per supportarlo. –

+0

@MatthewWatson Più un caso di vedere il pattern matching di F # e di voler fare qualcosa di più vicino a questo, risolvendo questa volontà (spero) diventi parte del C# 7. – Richard

0

Basato su richiesta OP:

private static bool IsIntValid(string str) 
{ 
    int i = 0; 
    return int.TryParse(str, out i); 
} 

Certo non l'approccio più intelligente tuttavia, il più semplice immagino:) Può anche avvolgere questo in un metodo di estensione.

+0

Che un po 'complicato, ma grazie per aver spiegato. –

4

dichiarazioni in linea per out parametri è una nuova funzione suggerita in C# che potrebbe essere standard un giorno, vedere ad es. Probable C# 6.0 features illustrated, sezione 9. Il previsto/proposta di sintassi:

int.TryParse("5", out int x); // this declares (and assigns) a new variable x 

Edit: Questo out sintassi variabile è stata poi inclusa in C# 7.0 (Visual Studio 2017); puoi anche usare out var x.


Aggiunta: le persone escono con metodi di estensione divertenti. Ho provato a fare un generico:

public delegate bool TryParser<TResult>(string s, out TResult result); 

public static class FunExtensions 
{ 
    public static T TryParse<T>(this string str, TryParser<T> tryParser) 
    { 
    T outResult; 
    tryParser(str, out outResult); 
    return outResult; 
    } 
} 

Questo può essere utilizzato in questo modo:

var x = "5".TryParse<int>(int.TryParse); 
    var y = "01/01".TryParse<DateTime>(DateTime.TryParse); 
    var z = "bad".TryParse<decimal>(decimal.TryParse); 

e così via. Speravo il compilatore dedurre T da uso, in modo che si potrebbe dire semplicemente:

var x = "5".TryParse(int.TryParse); // won't compile 

ma sembra si deve specificare in modo esplicito il tipo di argomento del metodo.

3

Come una soluzione è possibile creare un interno:

public static int TryParse(this string input, int defaultValue = default(int)) 
{ 
    int intOutParameter; 
    bool parsable = int.TryParse(input, out intOutParameter); 
    if (parsable) 
     return intOutParameter; 
    else 
     return defaultValue; 
} 

Allora non hanno nemmeno bisogno di un out -parameter:

int parsed = "5".TryParse(0); 
+0

modo complicato per risolvere il problema. –

+0

Ma cosa succede se voglio renderlo più generico? Voglio dire 'Guid.TryParse' e' TimeSpan.TryParse' ecc. Ho provato un'estensione generica nella mia risposta. –

0

È inoltre possibile utilizzare un deposito temporaneo per tutti i metodi.

public static class Tmp<T> 
{ 
    [ThreadStatic] 
    public static T Value; 
} 

int x = int.TryParse("5", out Tmp<int>.Value) ? Tmp<int>.Value : 0; 
+0

molto interessante, ma è così efficiente? –

+0

Non vedo perché questo dovrebbe essere inefficiente. Nessun oggetto viene creato, solo un tipo generico viene creato una volta utilizzato. – IllidanS4

Problemi correlati