2016-11-23 4 views
0

Ich hatte mehrere Erweiterungsmethoden wie ParseInt, ParseLong, ParseByte. jetzt versuche ich eine einzige Erweiterungsmethode für alle von ihnen zu machen. das Problem ist, dass der Default Parameter optional machen ich es einen Wert wie T Default = 0 geben, aber es erzeugt den Fehler:T Typ Standardwert

A value of type 'int' cannot be used as a default parameter because there are no standard conversions to type 'T'

Wenn ich es wie T Default = (T)0 verwenden dann bekomme ich einen anderen Fehler:

Cannot convert type 'int' to 'T'

Das ist meine Erweiterungsmethode:

public static T Parse<T>(this string x, T Default = 0) 
     { 
      Type type = typeof(T); 
      if(type == typeof(int)) 
      { if(!string.IsNullOrEmpty(x) int.TryParse(x , out Defualt); return Default; } 
     } 
+2

nicht sicher, den Punkt zwischen der Verwendung von 'Parse 'oder' ParseInt' in beiden Fällen zu sehen, müssen Sie "explizit" über den Rückgabetyp sein – Sehnsucht

+0

@AshkanMobayenKhiabani: Einige off-topic Tipps. ** 1. ** Anstelle von 'typeof (T) == typeof (int)' könnte man einfach 'Default is int 'wählen. ** 2. ** Parameternamen beginnen normalerweise mit einem kleinen Buchstaben. Nun ist 'default' bereits ein C# -Schlüsselwort, aber Sie können Ihren Parameter immer noch aufrufen, indem Sie ihn umgehen:' @ default'. Natürlich könnte es auch angenehmer sein, den Parameter stattdessen in 'defaultValue' umzubenennen. – stakx

Antwort

5

Sie können default(T) nur statt:

public static T Parse<T>(this string x, T defaultValue = default(T)) 

Allerdings würde ich das Design hier stark in Frage stellen - Sie schreiben nicht wirklich eine generische Methode, sondern eine Methode, die einen bestimmten Typ von Typen akzeptiert und jede unterschiedlich behandelt. Es gibt Zeiten, in denen dies auf Sie durchgesetzt wird, aber ich würde in der Regel eine Dictionary<T, SomeDelegate> haben, um zu versuchen, damit sauberer umzugehen.

Außerdem werde ich immer noch Probleme int.TryParse Aufruf haben - Sie nicht den Parameter auf Parse<T> als Argument verwenden können - Sie so etwas wie bräuchten:

if (typeof(T) == typeof(int)) 
{ 
    // You need to consider what you want to happen if 
    // int.TryParse returns false - do you want to return 0, 
    // or defaultValue? 
    int ret; 
    if (int.TryParse(x, out ret)) 
    { 
     // Annoying but required due to which conversions are available 
     return (T)(object) ret; 
    } 
} 
return defaultValue; 
+0

vielen Dank. Du hast meinen Tag gemacht –

+0

Ich habe es nicht bekommen, was ist die Verwendung von Dictionary hier –

+0

@AshkanMobayenKhiabani: Sie hätten einen Delegierten für jede Implementierung, die Sie nach Typ nachschlagen könnten. Es vermeidet, eine sehr lange Methode zu haben. –

1

Wie andere Antwort bereits erwähnt Sie können den Standardwert eines generischen Typs als Kompilierzeitkonstante abrufen, indem Sie in Ihrem Fall das Schlüsselwort default verwenden: default(T).

  • T Wenn eine Klasse oder Schnittstellentyp, der null default(T) Referenz.
  • Wenn T eine Struktur ist, dann ist default(T) der Wert, bei dem alle Bits null sind. Dies ist 0 für numerische Typen, false für bool, und eine Kombination dieser beiden Regeln für benutzerdefinierte struct s.

Aber: Tu das nicht. Erstellen Sie diese generische Methode nicht, wenn es nur für einige handverlesene Typen funktioniert. Als allgemeine Regel gilt, dass generische Methoden für alle Typen arbeiten sollen. (Sie können die gültigen Typen mit generischen Parametereinschränkungen beschränken where T : … aber das bedeutet nicht, die Grundidee ändern.)

In Ihrem Fall die generische Methode wird nur für ein paar Typen wie int arbeiten, long, float, double, decimal, usw. Sie müssen sogar in Ihrer generischen Methode bereits nach diesen Typen suchen, damit Sie auf die richtige Methode (int.TryParse, double.TryParse, usw.) verzichten können. Das ist ein großes Zeichen, dass Ihre Methode überhaupt nicht generisch sein sollte.

Bleiben Sie mit Ihrer bisherigen Erweiterungsmethode ParseInt, ParseSingle, ParseDouble usw. Es war das bessere Design.

Verwandte Themen