Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port FxCop rule CA1011: ConsiderPassingBaseTypesAsParameters #375

Open
ghost opened this issue Nov 21, 2015 · 11 comments · May be fixed by #5356
Open

Port FxCop rule CA1011: ConsiderPassingBaseTypesAsParameters #375

ghost opened this issue Nov 21, 2015 · 11 comments · May be fixed by #5356
Assignees
Labels
Bug The product is not behaving according to its current intended design FxCop-Port help wanted The issue is up-for-grabs, and can be claimed by commenting
Milestone

Comments

@ghost
Copy link

ghost commented Nov 21, 2015

Title: Consider passing base types as parameters

Description:

When a base type is specified as a parameter in a method declaration, any type that is derived from the base type can be passed as the corresponding argument to the method. If the additional functionality that is provided by the derived parameter type is not required, use of the base type enables wider use of the method.

Dependency: None

Notes:

@ghost ghost added the FxCop-Port label Nov 21, 2015
@natidea natidea self-assigned this Jan 19, 2016
natidea added a commit to natidea/roslyn-analyzers that referenced this issue Apr 5, 2016
@natidea
Copy link
Contributor

natidea commented Apr 5, 2016

@jinujoseph jinujoseph assigned 333fred and unassigned natidea Sep 26, 2017
@jinujoseph jinujoseph added this to the 15.5 milestone Sep 26, 2017
@jinujoseph jinujoseph added the Bug The product is not behaving according to its current intended design label Nov 27, 2017
@mavasani mavasani modified the milestones: 15.5.Later, 15.6 Dec 12, 2017
@333fred
Copy link
Member

333fred commented Dec 22, 2017

@dotnet/roslyn-analysis @sharwell @kuhlenh I'd like some input on how correct we think the fixer for this should be. For example:

interface I1 {}
class Foo : I1 {}

class Bar
{
    void Baz(I1 i1) { }
    void Baz(Foo foo)
    {
        // Uses only I1 functionality
    }
}

In this case, if we offer to fix Baz(Foo) so it takes Baz(I1), there will be an error in the resulting code, as there's two identical Baz signatures. Personally, I think the incorrectness is ok in this scenario. For FixAll scenarios of this, there are possibilities that we end up fixing multiple methods such that they clash after both have been fixed, and that's not detectable until we actually have all things that need to be fixed. FXCop didn't have any logic for detecting whether fixing the issue would result in this breaking, so I'm thinking we shouldn't either.

@jamesqo
Copy link
Contributor

jamesqo commented Dec 22, 2017

I think there are cases in which this fix should not be applied, e.g. when the type encodes information about what the object represents. One example:

interface IResource {
    string Location { get; }
}

class FileResource : IResource {
    // Location represents a file path
}
class HttpResource : IResource {
    // Location represents an HTTP url
}

// Should not be corrected to IResource
string GetContent(FileResource res) {
    return File.ReadAllText(res.Location);
}

@333fred
Copy link
Member

333fred commented Dec 22, 2017

That's not something we're able to detect from the analyzer, though. If the user has a legitimate reason to not use the base class/interface, they can suppress the warning.

@jamesqo
Copy link
Contributor

jamesqo commented Dec 23, 2017

@333fred

they can suppress the warning.

I don't think there should be a warning in the first place. The term slipped my mind before, but types of this kind are actually so common that they have a term for them-- "marker interfaces" (e.g. interfaces with no members). Enabling this analyzer would issue a warning every time a marker interface would passed to a method, potentially resulting in a huge number of warnings for large codebases/people just disabling the analyzer entirely.

I think Info would be more appropriate.

@sharwell
Copy link
Member

Enabling this analyzer would issue a warning every time a marker interface would passed to a method, potentially resulting in a huge number of warnings for large codebases/people just disabling the analyzer entirely.

This diagnostic should only be reported when the method only uses members that are defined in the base type. Under these rules marker interfaces would typically not trigger this.

@sharwell
Copy link
Member

In this case, if we offer to fix Baz(Foo) so it takes Baz(I1), there will be an error in the resulting code, as there's two identical Baz signatures. Personally, I think the incorrectness is ok in this scenario.

We should avoid reporting a diagnostic if another overload exists that already takes the base type.

@333fred
Copy link
Member

333fred commented Dec 27, 2017

@sharwell yes, that was on my list of things to test.

@333fred
Copy link
Member

333fred commented Jan 30, 2018

@sharwell I think I misunderstood your commend when I originally replied. How would you suggest dealing with multiple methods that can be simplified to the same base-type in the fix-all scenario? Personally, I think that if the user has a legitimate reason to not use the base type (and probably merge this method and the conflicting implementation) then they should suppress the warning and indicate why in their code.

@jinujoseph jinujoseph modified the milestones: 15.6, 15.7 Feb 20, 2018
@jinujoseph jinujoseph modified the milestones: 15.7, 15.8 Apr 25, 2018
@mavasani mavasani removed this from the 15.8 milestone Jul 1, 2019
@mavasani mavasani added this to the Unknown milestone Jul 1, 2019
@sharwell sharwell added help wanted The issue is up-for-grabs, and can be claimed by commenting and removed Up for Grabs labels Aug 1, 2019
@Evangelink
Copy link
Member

We shall be careful with how we implement this rule. I have seen quite a lot of wrong behaviors from people following this rule from ReSharper (especially around IEnumerable<T>).

Also when implementing this rule by myself, I have noticed that when implementing analyzers most of the time I was creating private methods taking a specific node type in parameter and the rule was suggesting to use SyntaxNode instead which is ok from the point of view of the APIs I was using but wrong from the point of view of the shape.

@carlossanlop
Copy link
Member

FYI - the proposal has been approved: dotnet/runtime#61916 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug The product is not behaving according to its current intended design FxCop-Port help wanted The issue is up-for-grabs, and can be claimed by commenting
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants