views:

94

answers:

3

Hello,

I have the following (simplified) method:

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

At the cast "(DateTime)val" I get the following error:

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

What can I do to access the Year property of the DateTime parameter?

UPDATE: Thank you for all your very fast answers. This method (and method name) is really (!) simplified to show exactly my problem and to let everyone just copy&paste it into his own visual studio. It is just that I wanted to add some Type specific values if the type is a DateTime. Beside that 99% of the method is the same.

+4  A: 

Change it to

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

To answer the question, the compiler does not realize that T is DateTime.
To perform this cast, you need to cast through object, like this:

    return ((DateTime)(object)val).Year.ToString("0000");
SLaks
James Curran
@James: AFAIK, there is no way to avoid that without making a separate method.
SLaks
@SLaks: I agree, but it should be noted.
James Curran
+1  A: 

SLaks types faster than I do. :)

But let me add: you might want to re-think your implementation, here, depending on what you're trying to achieve. I assume the reason to have a generic GetStringFromValue method is to emit specific strings from various types. But that's going to end up a bit of a mess once you have, say, a dozen different types in there.

If they're System types, such as DateTime, string.Format() can probably handle all of them, with appropriate format strings. If they're your own types, consider overriding their ToString() methods.

Either way, a little more detail on the problem you're solving would make for interesting answers.

djacobson
+4  A: 

I know you said the example was simplified, but consider handling it like this:

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

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

The DateTime overload is the best match when an actual DateTime is passed, and the generic version will be used for everthing else. (You could even forgo generic for the second one, and just use an Object)

James Curran
upvote for the separate methods for each type. Would it be better to use {0:yyyy} instead though?
gbogumil
or simply val.ToString("yyyy")
gbogumil
@gbogumil: val.ToString("yyyy") - This will give me the error: Method 'ToString' has 0 parameter(s) but is invoked with 1 argument(s)
Chris
but val is a DateTime type. It has 4 overloads on ToString.
gbogumil