Почему не могут быть выведены вложенные универсальные типы? - PullRequest
15 голосов
/ 09 июля 2011

Учитывая следующие классы ...

public abstract class FooBase<TBar> where TBar : BarBase{}
public abstract class BarBase{}
public class Bar1 : BarBase{}
public class Foo1 : FooBase<Bar1> {}

... и следующий метод ...

public TBar DoSomething<TFoo, TBar>(TFoo theFoo)
    where TFoo : FooBase<TBar>
    where TBar : BarBase
{
    return default(TBar);
}

Почему следующая строка кода не может подразумевать тип возвращаемого значения?

Bar1 myBar = DoSomething(new Foo1());

Вместо этого я должен указать общие типы, как это ...

Bar1 myBar = DoSomething<Foo1, Bar1>(new Foo1());

1 Ответ

21 голосов
/ 09 июля 2011

Вывод типа метода игнорирует общие ограничения на параметры типа метода (*).Вывод типа метода основывается только на выводах, которые можно сделать, сравнивая аргументы с формальными типами параметров .Поскольку единственным типичным параметром типа, который появляется в ваших формальных типах параметров, является TFoo, невозможно вывести TBar.

Многие люди считают, что это проектное решение неверно, неправильно, неправильно.Хотя я принимаю их точку зрения, это решение приводит к тому, что, на мой взгляд, есть хорошие свойства.Для расширенной дискуссии по этому вопросу см. Bazillion или около того комментарии к этой статье блога, говорящие мне, что я не прав, не прав, не прав:

http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx


(*)Обратите внимание, что я сказал, что ограничения на параметры типа метода игнорируются, а не ограничения вообще.Если выведенные формальные типы параметров конструируются универсальными типами, так что конструкция нарушает ограничения их параметров типа , то этот факт приводит к сбою вывода типа, и метод не является кандидатом для разрешения перегрузки.Но ни при каких обстоятельствах мы не делаем вычитание из ограничения, отличного от "Хмм, ясно, что это не сработает".

...