Почему я должен предоставлять явно общие типы параметров, в то время как компилятор должен выводить тип? - PullRequest
13 голосов
/ 18 декабря 2010

Почему я должен предоставлять явно общие типы параметров, в то время как компилятор должен выводить тип?

public static T2 Cast<T1,T2>(this T1 arg) where T2 : class where T1 : class
{
    return arg as T2;
}

Пример использования:

 objOfTypeT2 = objOfTypeT1.Cast<TypeT1,TypeT2>();


По сравнению с моим желаемым использованием с более интеллектуальным компилятором:

 objOfTypeT2 = objOfTypeT1.Cast<TypeT2>();

или, может быть, я должен быть умнее: -)

Остерегайтесь, что Я предоставляю тип возврата . Я не хочу предоставлять объект, который я вызвал функцию, это метод Расширение .

Ответы [ 3 ]

18 голосов
/ 18 декабря 2010

Вывод не учитывает тип возвращаемого значения;однако вы можете попробовать разделить дженерики;например, вы могли бы написать код, чтобы разрешить:

.Cast().To<Type2>()

, имея (не проверено; только для указания)

public static CastHelper<T> Cast<T>(this T obj) {
    return new CastHelper<T>(obj);
}
public struct CastHelper<TFrom> {
    private readonly TFrom obj;
    public CastHelper(TFrom obj) { this.obj = obj;}
    public TTo To<TTo>() {
       // your code here
    }
}
13 голосов
/ 18 декабря 2010

Спецификация ограничивает вывод параметров типа для универсальных методов всеми или ничем. Вы не можете иметь частичный вывод.

Обоснование, вероятно, упрощает правила вывода типов (которые уже довольно сложны, поскольку они также должны учитывать правила перегрузки).

2 голосов
/ 14 августа 2018

Я использовал решение Марка Гравелла и мне понравилось, но я могу представить другую альтернативу.

Поскольку общие параметры выводятся из параметров, другой вариант заключается в использовании параметра out для результата вместовозвращаемое значение.

Это было возможно в течение длительного времени, но сегодняшний C # позволяет вам объявить переменную inline, которую я считаю пригодным для использования потоком.

public static void Cast<T1, T2>(this T1 arg, out T2 result) where T2 : class where T1 : class
{
    result = arg as T2;
}

Вы можете вызвать это следующим образом

objOfTypeT1.Cast(out Type2 objOfTypeT2);
...