Skip to content

Conversation

@xtqqczze
Copy link
Contributor

PR Summary

Autofix GU0073: Member of non-public type should be internal.

https://github.com/GuOrg/Gu.Analyzers/blob/master/documentation/GU0073.md

PR Context

PR Checklist

@rjmholt
Copy link
Collaborator

rjmholt commented Aug 14, 2020

From #13425 (comment):

Generally I personally prefer public methods on internal and private classes; a class/object has a public API and private methods, internal implies a secondary API and muddies thinking around the cohesion and contract around a class. More than that, keeping members public is arguably DRYer, since the API represented by the class now has its exposure controlled by a single keyword at the class level.

However, in PowerShell there is a consideration that once you have an object, any public member on it is visible to PowerShell (even if the class itself is internal), which drives a lot of the other classes that have internal members on everything. So there is an externally appreciable difference between an internal type with public members and an internal type with internal members. While we don't consider an internal change like that to be breaking, it's still a change that could affect users.

@iSazonov
Copy link
Collaborator

it's still a change that could affect users

If you say about reflection it is never public contract.

@rjmholt
Copy link
Collaborator

rjmholt commented Aug 14, 2020

If you say about reflection it is never public contract.

Agreed. My question is that there's a change being made, but for what benefit? It's not a public contract, but it may still complicate things for users. I would want to see a positive effect in exchange for that.

@xtqqczze
Copy link
Contributor Author

xtqqczze commented Aug 14, 2020

This PR will require more effort before it can be built successfully.

I think the only benefit is in code review (easy to verify a method is not public API), so if this change could affect users I think it may not bring value. I wonder what other maintainers think.

Once we have made a decision we could consider documenting in our coding guidelines.

@xtqqczze xtqqczze marked this pull request as ready for review August 14, 2020 20:04
@xtqqczze xtqqczze marked this pull request as draft August 14, 2020 20:04
@iSazonov
Copy link
Collaborator

In my opinion, it is better to follow the principle of minimum visibility.

@SeeminglyScience
Copy link
Collaborator

Echoing @rjmholt's point, I see a lot of members "accidently" surfaced to PowerShell like this. Say you have an API like this:

public abstract class Food { }

internal class Apple : Food
{
    public int SeedCount { get; set; }
}

public static class Store
{
    public static Food GetFood()
    {
        return new Apple();
    }
}

If you call [Store]::GetFood() | Get-Member, the user has no way of knowing SeedCount isn't something they're supposed to be able to use. Making a blanket change like this is pretty dangerous.

I took a quick glance over some of the changes and pretty quickly found one example of this, the formatting objects like FormatStartData. There's no way to know that all of those properties are not part of breaking change contracts. I've definitely seen code relying on these.

@ghost ghost added the Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept label Aug 20, 2020
@xtqqczze xtqqczze closed this Aug 22, 2020
@xtqqczze xtqqczze deleted the GU0073 branch August 22, 2020 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants