diff --git a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs index 03393914ca77d2fdb03ed1041c7e532a93d65328..40ec60890560d3addb2fb240cb7036e57e6a1979 100644 --- a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs +++ b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs @@ -8234,5 +8234,42 @@ public int Baz([AllowNull] int bar) }} }}"); } + + [WorkItem(13427, "https://github.com/dotnet/roslyn/issues/13427")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)] + public async Task TestDoNotAddNewWithGenericAndNonGenericMethods() + { + await TestWithAllCodeStyleOptionsOffAsync( +@"class B +{ + public void M() { } +} + +interface I +{ + void M(); +} + +class D : B, [|I|] +{ +}", +@"class B +{ + public void M() { } +} + +interface I +{ + void M(); +} + +class D : B, I +{ + public void M() + { + throw new System.NotImplementedException(); + } +}"); + } } } diff --git a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs index 9241c9606bbb3abbe453e1edc56d9e3362187bf5..5ceb4e23749c12ff0d6ab736d139f7c1c5ca832e 100644 --- a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs +++ b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs @@ -440,30 +440,19 @@ private ISymbol GenerateEvent(Compilation compilation, string memberName, bool g return baseTypes.Any(ts => ts.GetMembers(memberName) .Where(m => m.IsAccessibleWithin(State.ClassOrStructType)) - .Any(m => HasNameConflict(member, memberName, m))); + .Any(m => HasNameConflict(member, m))); } - private static bool HasNameConflict( - ISymbol member, - string memberName, - ISymbol baseMember) + private static bool HasNameConflict(ISymbol member, ISymbol baseMember) { - Debug.Assert(memberName == baseMember.Name); - - if (member.Kind == SymbolKind.Method && baseMember.Kind == SymbolKind.Method) + if (member is IMethodSymbol method1 && baseMember is IMethodSymbol method2) { // A method only conflicts with another method if they have the same parameter // signature (return type is irrelevant). - var method1 = (IMethodSymbol)member; - var method2 = (IMethodSymbol)baseMember; - - if (method1.MethodKind == MethodKind.Ordinary && - method2.MethodKind == MethodKind.Ordinary && - method1.TypeParameters.Length == method2.TypeParameters.Length) - { - return method1.Parameters.Select(p => p.Type) - .SequenceEqual(method2.Parameters.Select(p => p.Type)); - } + return method1.MethodKind == MethodKind.Ordinary && + method2.MethodKind == MethodKind.Ordinary && + method1.TypeParameters.Length == method2.TypeParameters.Length && + method1.Parameters.SequenceEqual(method2.Parameters, SymbolEquivalenceComparer.Instance.ParameterEquivalenceComparer); } // Any non method members with the same name simple name conflict.