Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
154 views
in Technique[技术] by (71.8m points)

c# - Why can't I cast int to T, but can cast int to object and then object to T?

This code does not compile:

public T Get<T>()
{
    T result = default(T);
    if(typeof(T) == typeof(int))
    {    
        int i = 0;
        result = (T)i;
    }

    return result;
}

however, this code does compile:

public T Get<T>()
{
    T result = default(T);
    if(typeof(T) == typeof(int))
    {    
        int i = 0;
        result = (T)(object)i;
    }

    return result;
}

The code also works fine. I don't understand why the compiler can cast an object (actual type could be anything) to T, but cannot cast an int (which inherets from object) to T.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As SLaks says, the compiler knows that T is convertible to object but that's only half of it. The compiler also knows that any object of type T derives from object, so it needs to allow downcast from object to T. Collections pre v2.0 needed this. Not to T of course but to be able to downcast from object to any type. It would have been impossible to get anything out of a collection as anything else than an object.

The same is not true when talking about T and int. Your code is of course safe from those problems at runtime due to the if statement, but the compiler can't see that. In general (not in this case though) proving that you will never get to the body of an if in the case of some external condition being true is NP-complete and since we wish the compiler to complete at some point, it's not going to try and basically solve a millennium prize problem

There are many scenarios where substituting a specific type for T would not be allowed in non-generic code.

If you can't write the code as non-generic for any substitution of T with a specific type, it's not valid, not just in this case but generally. If you know that for all your use cases of the method it would actually be valid, you can use constraints to your generic method.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...