Почему я не могу привести int к T, но могу привести int к объекту, а затем к T? - PullRequest
5 голосов
/ 23 декабря 2011

Этот код не компилируется:

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

    return result;
}

однако этот код компилируется:

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

    return result;
}

Код также работает нормально.Я не понимаю, почему компилятор может привести объект (фактический тип может быть чем угодно) к T, но не может привести int (который наследует от объекта) к T.

Ответы [ 2 ]

9 голосов
/ 23 декабря 2011

Как говорит SLaks , компилятор знает, что T можно преобразовать в объект, но это только половина. Компилятору также известно, что любой объект типа T является производным от object, поэтому ему необходимо разрешить понижение с object до T. Коллекции pre v2.0 нуждались в этом. Не для T конечно, но чтобы можно было опускать от объекта до любого типа. Было бы невозможно извлечь что-либо из коллекции, как что-либо еще, кроме объекта.

То же самое не верно, когда речь идет о T и int. Ваш код, конечно, защищен от этих проблем во время выполнения из-за оператора if, но компилятор этого не видит. В общем (но не в этом случае) доказательство того, что вы никогда не получите тело тела if, если в случае некоторого внешнего условия истинно равен NP-complete , и так как мы хотим, чтобы компилятор завершил работу в некотором точка, это не собирается пытаться и в основном решить проблему премии тысячелетия

Существует много сценариев, в которых замена определенного типа на T не будет разрешена в неуниверсальном коде.

Если вы не можете написать код как неуниверсальный для какой-либо замены T конкретным типом, это недопустимо, не только в этом случае, но и вообще. Если вы знаете, что для всех ваших случаев использования метода он действительно будет действительным, вы можете использовать ограничений для вашего универсального метода.

6 голосов
/ 23 декабря 2011

Компилятор не знает, что T равно int.(даже если вы только что доказали, что int в вашем if)

В отличие от этого, компилятор знает, что T всегда можно преобразовать в object.

ДляНапример, если T равно string, оно все еще может быть преобразовано в object, но не может быть преобразовано в int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...