如果声明是接口,则编译器不会识别泛型中的属性

时间:2018-03-15 19:16:34

标签: c# visual-studio

看一下以下演示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方法中创建断点并希望查看Key Visual Studio的foo属性时,不会为我提供工具提示。 通过将foo.Key添加到监视窗口,我收到以下错误:

  

错误CS1061:&#39; T&#39;不包含&#39; Key&#39;的定义和不   扩展方法&#39; Key&#39;接受第一个类型&#39; T&#39;可能   发现(您是否缺少using指令或程序集引用?)

当我将通用声明更改为Foo而不是IFoo时,编译器可以访问&#39;键&#39;财产,所以这个:

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.Key添加到观察窗口或将?foo.Key写入即时窗口会带来上述错误,当您将鼠标移到Key foo.Key时,您将无法获得工具提示/ p>

使用Visual Studio 2015,2017测试。

Error in watch VS window

2 个答案:

答案 0 :(得分:5)

此问题有两种解决方法。使用工具&gt;选项&gt;调试&gt;一般。您可以勾选&#34;使用托管兼容模式&#34;或&#34;使用传统的C#和VB.NET表达式评估程序&#34;。

&#34;使用托管兼容模式&#34;它是不必要的神秘,它实际上做的是用VS2010上次使用的调试引擎替换新的调试引擎。好的。它实际上也为您提供了遗留表达式评估程序。我建议你使用这个,因为它还避免了新调试引擎中的一堆其他错误。这在VS2015中特别错误。

我发现很少有理由将其关闭。您错过了最近添加的调试器功能,我只知道方法返回值检查,编辑+继续64位代码以及在非Windows系统上.NETCore中使用的新的可移植PDB格式。 必须用于调试C ++ / CLI代码。我不知道新表达式评估器有什么好处,从来没有注意到任何东西。没有它们很容易生活,至少对我而言。

我对调试器团队的内部人员的了解并不足以确切地说明发生了什么。但它看起来并不好看,VS2017增加了一些新的令人讨厌的故障模式,新的调试引擎在最糟糕的时候坍塌成一堆废墟。从他们的面值看这些选项,他们肯定存在,因为他们知道最新版本不符合要求。

更新:正如兰德所指出的那样,这个特殊的缺陷似乎已得到解决。我在版本15.9.3中看到了正确的行为。

答案 1 :(得分:1)

错误已在Visual Studio 2019中修复: https://developercommunity.visualstudio.com/content/problem/216341/compiler-doesnt-recognise-property-in-generic-if-d.html

Ivan Basov [MSFT]评论:

  

在当前的Visual中似乎无法重现该问题   工作室。我在VS 2019 Preview 2中进行了尝试。该方案工作正常。   谢谢您的反馈!

还尝试在我的预览版1.1上重现它,并且它也在那里修复。

还尝试提供最新版本的Visual Studio 2017(15.9.5),并可以报告该版本已修复。