Reputation: 8462
This is a question for the .NET philosophers:
It is my understanding that Microsoft consciously denied use of private classes in C#. Why did they do this and what are their arguments for doing so?
I, for example, am building a large application that includes a reporting tool. This tool uses a lot of business objects that are used only within the reporting tool and not in other parts of the project. I want to encapsulate them for use only within the reporting tool itself.
Great decision is creating separate project in VS for this tool, and I'll do like that, but I'm interesting, what if I can't do this - for exmple our architecture wasn`t good enough, and we have big single project.
Behind "private class" I mean a class that can't be used in any other namespace, except its own.
My question was not - how can I simulate this, or do in another way. I'm just wondering, why not use private keyword with class keyword without any parent classes. I`m thinking there should be some reason, and I want to know it
Upvotes: 23
Views: 25226
Reputation: 56467
There's a workaround for this, but you might not like it.
Instead of using a namespace
to scope your classes, use a public static partial class
:
Before:
namespace MyCompany.Foo {
class Bar { }
public class Baz { }
}
After:
namespace MyCompany {
public static partial class Foo {
private class Bar { }
public class Baz { }
}
}
This construct, like a namespace, can span multiple files in the same project. But unlike a namespace, it cannot "escape" from your project (other projects cannot define other members inside Foo
).
There's an added advantage that you can have utility methods that seem to have no class for code inside Foo
.
The disadvantage is that, to use your non-private classes outside of your fake namespace, you have to reference them inside Foo
:
using MyCompany;
// ...
var baz = new Foo.Baz();
This can be mitigated by using an alias for the class:
using Baz = MyCompany.Foo.Baz;
// ...
var baz = new Baz();
But you'd have to do it for each non-private class that you want to use.
UPDATE
It's interesting to note that C# 6 will have static using statements, which could effectively improve this proposal to use a public static partial class
as a "module". You would just "use" the "module" to access its types directly.
Hopefully, it will work like this:
using MyCompany.Foo;
// ...
var baz = new Baz();
Just as if Foo
was a namespace.
Upvotes: 16
Reputation: 2601
So I guess you want to do this
namespace Baz
{
private class foo
{
private int _bar;
}
}
If yes. Then what is the purpose foo will server. At namespace can you be more restrictive than internal , and make any use of the class.If I could do this where will I use this .
That is why you have this compile time validation.
Now Inside a Public Class it makes sense to have a private class. I cannot explain it better this Private inner classes in C# - why aren't they used more often?.
Upvotes: 1
Reputation: 6209
Allowing classes to be private to a namespace would achieve no meaningful level of protection.
Any assembly in the world could simply reference your dll, and start writing code in your namespace which accesses your supposedly private classes.
I think that's possibly the answer you'd get from Microsoft.
Upvotes: 21
Reputation: 38130
You can define a private class, but it can only be used by its containing class.
If you want a class that is only visible within a particular assembly (DLL/EXE/etc.), then you should declare it as internal
(Friend
in VB)
Upvotes: 2
Reputation: 108975
You can create a private class, as a member of another type:
public class Outer {
// ...
private class Inner {
// ...
}
}
and Inner
is only visible to members of Outer
.
At the outermost level (i.e. in a namespace) private
as per its definition would not make sense (since there is nothing to be private in). Instead use internal
(visible to the containing assembly's members only).
Upvotes: 11
Reputation: 65476
True but you can get a pretty close simulation of this with internal classes and the internalsvisibletoAttribute if the namespace is split across multiple assemblies.
Also remember that a class within another can be private to the outer class. The outer class can be considered a namespace for this purpose.
Upvotes: 1