2010-08-24 6 views
13

Ich habe folgende (vereinfachte) Methode:Cast T-Parameter in der generischen Methode Datetime

private static string GetStringFromValue<T>(T val) 
{ 
    if (typeof(T) == typeof(DateTime)) 
    { 
     return string.Format("{0}", ((DateTime)val).Year.ToString("0000")); 
    } 
    return string.Empty; 
} 

Bei der Besetzung "(Datetime) val" Ich erhalte die folgenden Fehler:

Cannot cast expression of Type 'T' to type 'DateTime'

Was kann ich auf die Year-Eigenschaft des DateTime-Parameters zugreifen?

UPDATE: Vielen Dank für all Ihre sehr schnellen Antworten. Diese Methode (und der Methodenname) ist wirklich (!) Vereinfacht, um genau mein Problem zu zeigen und alle nur kopieren zu lassen & fügen Sie es in sein eigenes visuelles Studio ein. Es ist nur, dass ich einige typspezifische Werte hinzufügen wollte, wenn der Typ eine DateTime ist. Außerdem sind 99% der Methode gleich.

+1

Warum in aller Welt schreibst du 'String, Format (" {0} ", etwas)'? – SLaks

+0

Nicht nur das. 'something.ToString()'. – recursive

+0

Jahr ist nicht der einzige Wert, den ich bekommen möchte. Aber ich habe die Methode vereinfacht. Oder ist es falsch, dass ich String.Format überhaupt verwende? Es hat eine viel bessere Leistung und Lesbarkeit als: x.Year + ":" + x.Month + ":" + ..... – Chris

Antwort

24

ändern es zu

return string.Format("{0:yyyy}", val); 

die Frage zu beantworten, der Compiler nicht erkennen, dass TDateTime ist.
diese Besetzung ausführen zu können, müssen Sie durch object, wie diese werfen:

return ((DateTime)(object)val).Year.ToString("0000"); 
+5

Natürlich, wenn Sie durch Objekt werfen, gibt es Boxen & Unboxing Schritt weiter. –

+0

@ James: AFAIK, gibt es keine Möglichkeit, das zu vermeiden, ohne eine separate Methode zu machen. – SLaks

+1

Ich stimme zu, aber es sollte beachtet werden. –

1

SLaks Typen schneller als ich. :)

Aber lassen Sie mich hinzufügen: Sie möchten vielleicht Ihre Implementierung hier überdenken, je nachdem, was Sie erreichen möchten. Ich nehme an, der Grund für eine generische GetStringFromValue-Methode besteht darin, bestimmte Strings von verschiedenen Typen zu emittieren. Aber das wird ein bisschen durcheinander sein, wenn man, sagen wir mal, ein Dutzend verschiedener Typen drin hat.

Wenn es sich um Systemtypen wie DateTime handelt, kann string.Format() wahrscheinlich alle mit geeigneten Formatzeichenfolgen verarbeiten. Wenn es sich um eigene Typen handelt, sollten Sie ihre ToString() -Methoden überschreiben.

So oder so, ein bisschen mehr Details zu dem Problem, das Sie lösen, würden für interessante Antworten sorgen.

6

Ich weiß, Sie sagten das Beispiel vereinfacht wurde, aber bedenken Sie es wie folgt Handhabung:

private static string GetStringFromValue(DateTime val) 
{ 
    return string.Format("{0}", val.Year.ToString("0000")); 
} 

private static string GetStringFromValue<T>(T val) 
{ 
    return string.Empty; 
} 

Die Datetime-Überlastung ist das beste Spiel, wenn eine tatsächliche Datetime übergeben wird, und die generische Version wird für das Everthing verwendet werden sonst. (Du könntest sogar auf den zweiten verzichten und einfach ein Objekt verwenden)

+0

upvote für die separaten Methoden für jeden Typ. Wäre es besser, stattdessen {0: yyyy} zu verwenden? –

+0

oder einfach val.ToString ("yyyy") –

+1

@gbogumil: val.ToString ("yyyy") - Dies wird mir den Fehler geben: Methode 'ToString' hat 0 Parameter, wird aber mit 1 Argument (en) aufgerufen – Chris

Verwandte Themen