Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler doesnt recognise property in generic if declaration is an interface

Have a look at the following that demonstrates my issue with Visual Studio 2017 compiler

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);
    }
}

When I make a breakpoint inside the PrintFoo method and want to look at the Key property of foo Visual Studio wont provide a tooltip for me. By adding the foo.Key to the watch window I receive the following error:

error CS1061: 'T' does not contain a definition for 'Key' and no extension method 'Key' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?)

When I change the generic declaration to Foo instead of IFoo the compiler can acces the 'Key' property, so this:

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

Is there a way to make it work?

Edit:

Both, looking at the local window and mouse over foo to get the tooltip and than expanding the properties works.

Adding foo.Key to the watch window or writing ?foo.Key into immediate window brings the mentioned error, and you wont get a tooltip when you mouse over Key of foo.Key

Tested with Visual Studio 2015, 2017.

Error in watch VS window

like image 550
Rand Random Avatar asked Mar 15 '18 19:03

Rand Random


People also ask

Can a generic type be an interface?

Generics make a class, interface and, method, consider all (reference) types that are given dynamically as parameters. This ensures type safety. Generic class parameters are specified in angle brackets “<>” after the class name as of the instance variable. Generic constructors are the same as generic methods.

Can we use generic on interface in C#?

You can declare variant generic interfaces by using the in and out keywords for generic type parameters. ref , in , and out parameters in C# cannot be variant. Value types also do not support variance. You can declare a generic type parameter covariant by using the out keyword.

Can you create an instance of generic interface?

Constructing an Instance of a Generic TypeYou cannot create instances of it unless you specify real types for its generic type parameters.


2 Answers

There are two workarounds for this issue. Use Tools > Options > Debugging > General. You can tick "Use Managed Compatibility Mode" or "Use the legacy C# and VB.NET expression evaluators".

"Use Managed Compatibility Mode" is unnecessarily cryptic, what it actually does is replace the new debugging engine with the one that was last used in VS2010. The good one. It in effect also gives you the legacy expression evaluator. I recommend you use this one since it also avoids a bunch of other bugs in the new debugging engine. Which got especially buggy in VS2015.

Very few reasons I ever discovered to turn it back off. You miss out on recently added debugger features, I only know of method return value inspection, edit+continue for 64-bit code and the new portable PDB format that is used in .NETCore on non-Windows systems. It must be used to debug C++/CLI code. I don't know what is better about the new expression evaluator, never noticed anything. Pretty easy to live without them, at least for me.

I'm not privy enough to the internals of the debugger team to really tell what is going on. But it doesn't look that good, VS2017 added some new nasty failure modes with the new debugging engine collapsing into a pile of rubble at the worst possible time. Take these options at their face value, they surely exist because they know the latest versions are not up to snuff.


Update: as pointed out by Rand, this particular defect does appear to have been addressed. I'm seeing correct behavior in version 15.9.3.

like image 126
Hans Passant Avatar answered Nov 16 '22 00:11

Hans Passant


Bug got fixed in Visual Studio 2019: https://developercommunity.visualstudio.com/content/problem/216341/compiler-doesnt-recognise-property-in-generic-if-d.html

Comment by Ivan Basov [MSFT]:

It seems that the issue is not reproducible in the current Visual Studio. I tried it with VS 2019 Preview 2. The scenario works fine. Thank you for your feedback!

Also tried to reproduce it on my Preview Version 1.1 and it is fixed there aswell.

Gave the latest Version of Visual Studio 2017 (15.9.5) a try aswell and can report it got fixed there aswell.

like image 42
Rand Random Avatar answered Nov 16 '22 00:11

Rand Random