Я полагаю, это потому, что приведение к SomeClass
может означать любое количество вещей в зависимости от того, какие преобразования доступны, тогда как приведение к ISomeInterface
может быть только ссылочным преобразованием или преобразованием в бокс.
Параметры:
Сначала приведение к объекту:
SomeClass obj2 = (SomeClass) (object) t;
Используйте as
вместо:
SomeClass obj2 = t as SomeClass;
Очевидно, что во втором случае вам также потребуется выполнить проверку недействительности впоследствии, если t
равно , а не a SomeClass
.
РЕДАКТИРОВАТЬ: Обоснование этого приведено в разделе 6.2.7 спецификации C # 4:
Приведенные выше правила не допускают прямого явного преобразования из параметра типа без ограничений в тип без интерфейса, что может быть удивительным. Причина этого правила состоит в том, чтобы избежать путаницы и прояснить семантику таких преобразований. Например, рассмотрим следующую декларацию:
class X<T>
{
public static long F(T t) {
return (long)t; // Error
}
}
Если бы разрешено прямое явное преобразование t в int, можно легко ожидать, что X<int>.F(7)
вернет 7L. Однако это не так, потому что стандартные числовые преобразования рассматриваются только тогда, когда известно, что типы являются числовыми во время привязки. Чтобы прояснить семантику, вместо этого нужно написать приведенный выше пример:
class X<T>
{
public static long F(T t) {
return (long)(object)t; // Ok, but will only work when T is long
}
}
Этот код теперь будет компилироваться, но выполнение X<int>.F(7)
вызовет исключение во время выполнения, так как упакованный int не может быть напрямую преобразован в long.