Компилятор не распознает свойство в generic, если объявление является интерфейсом

Посмотрите на следующее, которое демонстрирует мою проблему с компилятором Visual Studio 2017

public interface IFoo
{
    string Key { get; set; }
}

public class Foo : IFoo
{
    public string Key { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        PrintFoo(new Foo() { Key = "Hello World" });
        Console.ReadLine();
    }

    private static void PrintFoo<T>(T foo) where T : IFoo
    {
        //set breakpoint here and try to look at foo.Key
        Console.WriteLine(foo.Key);
    }
}

Когда я делаю PrintFoo останова внутри метода PrintFoo и хочу посмотреть на свойство Key foo Visual Studio не предоставит мне всплывающую подсказку. Добавив foo.Key в окно просмотра, я получаю следующую ошибку:

ошибка CS1061: "T" не содержит определения для "Key", и метод расширения "Key", принимающий первый аргумент типа "T", не найден (отсутствует директива using или ссылка на сборку?)

Когда я изменяю обобщенное объявление на Foo вместо IFoo компилятор может получить доступ к свойству 'Key', вот так:

private static void PrintFoo<T>(T foo) where T : Foo
{
    //set breakpoint here and try to look at foo.Key
    Console.WriteLine(foo.Key);
}

Есть ли способ заставить его работать?

Редактировать:

Работает как просмотр локального окна, так и наведение foo на foo чтобы получить подсказку, а затем расширение свойств.

Добавление foo.Key в окно просмотра или запись ?foo.Key в непосредственное окно приводит к упомянутой ошибке, и вы не получите всплывающую подсказку при наведении мыши на Key of foo.Key

Протестировано с Visual Studio 2015, 2017.

Error in watch VS window

Ответ 1

Исправлена ошибка в Visual Studio 2019: https://developercommunity.visualstudio.com/content/problem/216341/compiler-doesnt-recognise-property-in-generic-if-d.html

Комментарий Ивана Басова [MSFT]:

Кажется, что проблема не воспроизводима в текущей Visual Studio. Я попробовал это с VS 2019 Preview 2. Сценарий работает отлично. Спасибо за ваш отзыв!

Также попытался воспроизвести его на моем Preview версии 1.1, и это исправлено там же.

Дайте также попробовать последнюю версию Visual Studio 2017 (15.9.5) и можете сообщить, что она там тоже исправлена.

Ответ 2

Есть два обходных пути для этой проблемы. Используйте Инструменты> Параметры> Отладка> Общие. Вы можете поставить галочку "Использовать режим управляемой совместимости" или "Использовать устаревшие оценщики выражений С# и VB.NET".

"Использовать управляемый режим совместимости" является излишне загадочным, фактически он заменяет новый механизм отладки на тот, который последний раз использовался в VS2010. Хороший. По сути, это также дает вам устаревший оценщик выражений. Я рекомендую вам использовать этот, поскольку он также позволяет избежать множества других ошибок в новом движке отладки. Что особенно глючило в VS2015.

Очень мало причин, которые я когда-либо обнаруживал, чтобы выключить его. Вам не хватает недавно добавленных функций отладчика, я знаю только проверку возвращаемого значения метода, редактирование + продолжение для 64-битного кода и новый формат переносимого PDB, который используется в .NETCore в системах, отличных от Windows. Он должен использоваться для отладки кода C++/CLI. Я не знаю, что лучше в новом оценщике выражений, никогда ничего не замечал. Довольно легко жить без них, по крайней мере, для меня.

Я недостаточно осведомлен о внутренностях команды отладчика, чтобы действительно сказать, что происходит. Но это не выглядит так хорошо, VS2017 добавил несколько новых неприятных режимов отказа, когда новый механизм отладки рухнул в кучу обломков в самый неподходящий момент. Возьмите эти варианты за чистую монету, они наверняка существуют, потому что они знают, что последние версии не подходят.


Обновление: как указал Рэнд, этот конкретный дефект, по-видимому, устранен. Я вижу правильное поведение в версии 15.9.3.