Why doesn't C# have package private?
Asked Answered
N

2

19

I'm learning C# and coming from a Java world, I was a little confused to see that C# doesn't have a "package private". Most comments I've seen regarding this amount to "You cannot do it; the language wasn't designed this way". I also saw some workarounds that involve internal and partial along with comments that said these workarounds go against the language's design.

Why was C# designed this way? Also, how would I do something like the following: I have a Product class and a ProductInstance class. The only way I want a ProductInstance to be created is via a factory method in the Product class. In Java, I would put ProductInstance in the same package as Product, but make its constructor package private so that only Product would have access to it. This way, anyone who wants to create a ProductInstance can only do so via the factory method in the Product class. How would I accomplish the same thing in C#?

Nobelium answered 11/2, 2011 at 1:55 Comment(2)
Make the Product classes constructor Private, then have a Public Static Function that returns a ProductInstance, eg: var p = Product.GetProductInstanceKerf
Looking at the answers, I see no answer to the why. I feel it is a big code smell setting a method internal where it is intended to be used only by a few "friendly" classes (see the friend keyword in C++). I don't want to break my application into hundreds of dll just to prevent smelly access, nor do I like to leave my detail implementation open (basically public to the whole dev team). Should I write giant classes with ten subclasses to overcome this limitation?Lyudmila
S
38

internal is what you are after. It means the member is accessible by any class in the same assembly. There is nothing wrong with using it for this purpose (Product & ProductInstance), and is one of the things for which it was designed. C# chose not to make namespaces significant -- they are used for organization, not to determine what types can see one another, as in java with package private.

partial is nothing at all like internal or package private. It is simply a way to split the implementation of a class into multiple files, with some extensibility options thrown in for good measure.

Sipe answered 11/2, 2011 at 1:59 Comment(7)
So I just need to mark ProductInstance's constructor as internal?Nobelium
@Vivin, yes, and presumably the class as well.Sipe
No, creating an assembly for just one factory class is bad advice. Having hundreds of assemblies makes a project hard to manage.Bonine
@miguel, that you have conflated my answer into advising one create a separate assembly for each class is rather surprising.Sipe
When you said "There is nothing wrong with using it for this purpose (Product & ProductInstance)" I took it to mean that you should create an assembly for this one purpose.Bonine
@miguel, I'm really confused by why you think the use of internal implies creating more assemblies. In fact, without jumping through hoops ([InternalsVisibleTo]) splitting classes into separate assemblies prohibits you from using internal.Sipe
OP's goal: The only way to create ProductInstance is via Product.factory. Your answer: use internal. But internal will still allow ProductInstance to be created via its constructor by other classes in the assembly. Therefore the only way your answer makes any sense is if Product and ProductInstnace are in their own assembly.Bonine
R
9

Packages don't really exist in the same way as they do in Java. Namespaces are used to organize code and prevent naming clashes, but not for access control. Projects/assemblies can be used for access control, but you can't have nested projects/assemblies like you can with packages.

Use internal to hide one project's members from another.

Runaway answered 11/2, 2011 at 2:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.