Skip to content

Suppress analyzer for properties with explicit interface implementation#23835

Merged
sharwell merged 4 commits intodotnet:dev15.6.xfrom
MaStr11:UseAutoPropertySuppressFixForExplicitInterface
Jan 23, 2018
Merged

Suppress analyzer for properties with explicit interface implementation#23835
sharwell merged 4 commits intodotnet:dev15.6.xfrom
MaStr11:UseAutoPropertySuppressFixForExplicitInterface

Conversation

@MaStr11
Copy link
Copy Markdown
Contributor

@MaStr11 MaStr11 commented Dec 18, 2017

Customer scenario

"Use auto property" code fix is provided for properties explicit interface implementations. The code fix generated invalid code. This fix suppress the code fixer for those properties.

Bugs this fixes

Fixes #23735

Workarounds, if any

Don't use the code fix.

Risk

Low.

Performance impact

The change causes an allocation of an immutable array on each "AnalyzeProperty" run.

Is this a regression from a previous update?

No.

Root cause analysis

Case wasn't covered by unit tests.

How was the bug found?

Customer reported

Test documentation updated?

No.

Remark

As discussed in #23735 (comment) there are cases where the analyzer actually could fix explicit implemented properties too, but this would probably do more harm than good. It would only work for read/write properties and every access to the backing field needs to be replaced by a cast to the interface:

namespace RoslynSandbox
{
    public interface IFoo
    {
        object Bar
        {
            get;
            set;
        }
    }
    internal class Foo : IFoo
    {
        private object bar;

        object IFoo.Bar
        {
            get
            {
                return this.bar;
            }
            set
            {
                this.bar = value;
            }
        }

        private void M()
        {
            this.bar = null;
        }
    }
}
namespace RoslynSandbox
{
    public interface IFoo
    {
        object Bar
        {
            get;
            set;
        }
    }
    internal class Foo : IFoo
    {
        object IFoo.Bar
        {
            get;
            set;
        }

        private void M()
        {
            ((IFoo)this).Bar = null;
        }
    }
}

return;
}

if (property.ExplicitInterfaceImplementations.Length != 0)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also test the accessibility as here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this disable the feature for VB as well as C#?

@sharwell
Copy link
Copy Markdown
Contributor

sharwell commented Jan 9, 2018

The change causes an allocation of an immutable array on each "AnalyzeProperty" run.

This is correct in the worst case, but in reality it's not quite this bad:

  • Properties that do not explicitly implement an interface property (the most important case) simply return ImmutableArray<T>.Empty without an allocation
  • At least in C#, most implementations of ExplicitInterfaceImplementations cache the underlying array, allowing it to be returned without an allocation


[WorkItem(23735, "https://github.com/dotnet/roslyn/issues/23735")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseAutoProperty)]
public async Task ExplicitInterfaceImplementation()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 It would be good to add a second test demonstrating the behavior for explicit interface properties that have both get and set.

@sharwell sharwell changed the base branch from master to dev15.6.x January 9, 2018 13:26
@sharwell sharwell added this to the 15.6 milestone Jan 9, 2018
@sharwell sharwell self-assigned this Jan 9, 2018
<WorkItem(23735, "https://github.com/dotnet/roslyn/issues/23735")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseAutoProperty)>
Public Async Function ExplicitInterfaceImplementation() As Task
Await TestMissingInRegularAndScriptAsync("
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we disabling things for VB? This is only a problem for C# right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. I changed the PR to suppress the fixer for C# only.

public async Task ExplicitInterfaceImplementationGetterOnly()
{
await TestMissingInRegularAndScriptAsync(@"
namespace RoslynSandbox
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nit. When making test cases, try to make them as small as possible (i'll admit we don't always follow that). So, remove things like unnecessary namespaces as they're not relevant to the fix.

Note: you don't have to change this. just something to keep in mind for the future.

Copy link
Copy Markdown
Contributor

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@sharwell
Copy link
Copy Markdown
Contributor

@Pilchie for ask mode

@Pilchie
Copy link
Copy Markdown
Member

Pilchie commented Jan 23, 2018

Approved for 15.6 Preview 4.

@sharwell sharwell merged commit 4abc5dd into dotnet:dev15.6.x Jan 23, 2018
@sharwell sharwell added the Community The pull request was submitted by a contributor who is not a Microsoft employee. label Jan 23, 2018
@MaStr11 MaStr11 deleted the UseAutoPropertySuppressFixForExplicitInterface branch March 2, 2018 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Approved to merge Community The pull request was submitted by a contributor who is not a Microsoft employee.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants