Archeg
Archeg

Reputation: 8462

Can you create private classes in C#?

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

Answers (6)

Jordão
Jordão

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

Ash
Ash

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

Alex Humphrey
Alex Humphrey

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

Rowland Shaw
Rowland Shaw

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

Richard
Richard

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

Preet Sangha
Preet Sangha

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

Related Questions