23

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

gonzobrains
  • 7,856
  • 14
  • 81
  • 132
Archeg
  • 8,364
  • 7
  • 43
  • 90
  • 13
    That's internal, not private. – Radoslav Hristov Aug 26 '10 at 10:58
  • 1
    Hey, I know what means internal, and private inside public =) I`m just wondering, why I can`t create private class for namespace - maybe it`s analog for all of this things, but why they denied this? – Archeg Aug 26 '10 at 11:03
  • 2
    @Archeg if it's private, who do you expect to be able to see it? – Rowland Shaw Aug 26 '10 at 11:08
  • other class that are created in the same namespace. When u are using simple principle - for a single folder in VS - single namespace - there will be use from this. U can use this class from the same folder, or folders that are inside it – Archeg Aug 26 '10 at 11:11
  • 7
    @Archeg: I think you think namespaces are more than they are. They are purely a naming context for code writers. Even at runtime they serve no purposes (all metadata and references are in terms of the full name). Remember an assembly can contain many namespaces and a namespace can be split across many assemblies. – Richard Aug 26 '10 at 11:24
  • Yeah I think you might be focusing too much on namespaces instead of looking to see how you can solve your problem. – Rangoric Aug 26 '10 at 12:22

6 Answers6

21

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.

Alex Humphrey
  • 6,099
  • 4
  • 26
  • 41
  • I like it, you caught my thought=) Could be the answer – Archeg Aug 26 '10 at 11:12
  • I can kind of see the value though - if you marked it as privatenamespace internal NewClass() {} That would protect against this. (Or if "privatenamespace" was implicitly internal.) – tim Aug 26 '10 at 11:31
  • 1
    @tim: I'm not sure I can. What I read the original question as saying is: "given that I've already got a mess of an architecture with not enough assembly-level encapsulation, why doesn't the language give me an alternative solution?" You shouldn't introduce language features as a workaround for bad architecture - you should encourage/enforce good architecture in the first place. – Dan Puzey Sep 03 '10 at 14:03
  • I am in a situation right now where a class private to a namespace would come in handy. It is old code and what is considered good architecture has changed since the framework was constructed. Plus data has changed. Plus Functionality has changed. Plus tooling has changed. It would be a good intermediary step to, sort of, simulate assemblies with the use of namespaces before taking a giant leap and refactor the architecture. This way I could sort of prove the benefit with the refactoring before asking anyone to spend €s on it. While keeping the system running without a big rewrite. – LosManos Mar 16 '15 at 13:37
16

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.

Jordão
  • 55,340
  • 13
  • 112
  • 144
  • 4
    No, I love your answer, it`s great! =) I will not use such idea because it could make my architecture very confusing. But, it`s really crushed my mind, it`s great example for seeing things different than the others seeing it. I think in future I could use some of the idea in special cases, tnx) Bad thing, as I remember, that vs and resharper ignores aliases (and some of the developers too) - for example they can`t go to definition for them. And in general, aliases is very confusing - you will not look there to find what the class is it, and what is it doing – Archeg Sep 04 '10 at 12:33
11

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).

Richard
  • 106,783
  • 21
  • 203
  • 265
  • Yeap, I know it. But it`s not the answer - I need to use my objects in multiply classes, and class with 20 inner classes is a problem =) – Archeg Aug 26 '10 at 11:04
2

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)

Rowland Shaw
  • 37,700
  • 14
  • 97
  • 166
1

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.

Preet Sangha
  • 64,563
  • 18
  • 145
  • 216
  • I wrote about internals. It`s cool but not the same. Maybe I have a situation, where I can`t divide my project into many – Archeg Aug 26 '10 at 11:06
1

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?.

Community
  • 1
  • 1
Ash
  • 2,531
  • 2
  • 29
  • 38