I've got an interface which supports nullable reference types:
interface ICache
{
bool TryOpen(string name, [NotNullWhen(true) ICacheItem? cacheItem);
}
In Visual Studio 16.6.5 if I implement the interface and let Visual Studio implement the interface for me I get this:
class TestCache : ICache
{
bool TryOpen(string name, [NotNullWhen(true) ICacheItem? cacheItem)
{
throw new NotImplementedException();
}
}
However, if I opt to explicitly implement the interface then Visual Studio doesn't add the nullable attributes:
class TestCache : ICache
{
bool ICache.TryOpen(string name, ICacheItem? cacheItem)
{
throw new NotImplementedException();
}
}
This causes a warning/error complaining that "cacheItem" doesn't match the implemented member.
Sounds like an issue for the Roslyn repo.
I've checked what's happening in the debugger and it turns out that when interface is being implemented explicitly all attributes for method parameters are being omitted
`srcWorkspacesCSharpPortableCodeGenerationParameterGenerator.cs:144
private static SyntaxList<AttributeListSyntax> GenerateAttributes(
IParameterSymbol parameter, bool isExplicit, CodeGenerationOptions options)
{
if (isExplicit)
{
return default;
}
var attributes = parameter.GetAttributes();
if (attributes.Length == 0)
{
return default;
}
return AttributeGenerator.GenerateAttributeLists(attributes, options);
}
`
Blaming the file didn't help since this logic was there from the very start of Roslyn repo. After I removed that check quick action started working as expected but several tests got broken in Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ImplementInterface.ImplementInterfaceTests: TestAttributesExplicit,TestIUnknownIDispatchAttributes2,TestOptionalDateTime2
If you look closely at the test suite code you'll notice that omitting attributes is expected behavior for " Implement interface explicitly" option - there are instances of these tests for implicit option and those have attributes placed in generated classes, but explicit version lack them. I wonder what was the logic behind that feature. There's a link to internal Microsoft TFS http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530265 maybe it says something about it.