views:

192

answers:

5

Why can I do this:

public T GetMainContentItem<T>(string moduleKey, string itemKey)
{
    return (T)GetMainContentItem(moduleKey, itemKey);
}

but not this:

public T GetMainContentItem<T>(string moduleKey, string itemKey)
{
    return GetMainContentItem(moduleKey, itemKey) as T;
}

It complains that I haven't restricted the generic type enough, but then I would think that rule would apply to casting with "(T)" as well.

+6  A: 

If T is a value type this is an exception, you need to make sure T is either Nullable or a class.

Yuriy Faktorovich
+23  A: 

Because 'T' could be a value-type and 'as T' makes no sense for value-types. You can do this:

public T GetMainContentItem<T>(string moduleKey, string itemKey)
    where T : class
{
    return GetMainContentItem(moduleKey, itemKey) as T;
}
n8wrl
Your answer is incorrect, you can cast on value types, the result will be nullable, see this post and the answer by Jon Skeet: http://stackoverflow.com/questions/496096/casting-vs-using-the-as-keyword-in-the-clr
Mikhail
+1  A: 

Is T a value type? If so, if the as operator fails, it will return null, which cannot be stored in a value type.

spoulson
A: 

Extending on Yuriy Faktorovichs answer:

public T GetMainContentItem<T>(string moduleKey, string itemKey) where T: class
{
    return GetMainContentItem(moduleKey, itemKey) as T;
}

This will do the trick...

EricSchaefer
A: 

Because as T retrieves null in case that it cannot cast to T as opposed to (T) that throws an exception. So if T is not Nullable or class it can't be null ... i think.

bruno conde