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
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.
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.
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).
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)
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.
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?.
Related
I have a public Library class with all the global variables needed for my program to work. It is structured like this:
public static class Library
{
public static string globalString = "";
}
In other languages, it is possible to use extends to extend a class to another class so the 'Library' prefix is not required on global variables but in C# it works a bit differently. I tried adding it after the colon in the class I wanted to extend to (like this: public partial class Login : Form, Library) and I was told that "Classes cannot have multiple base classes". Apparently, it is possible to use interfaces to extend classes but I do not fully understand how that works or how to implement it.
If you're using one of the newer versions of C#, you can import a static class so that you use its members without fully qualifying their names. In C#, the syntax would be...
using static RootNamespace.Library;
// Provided the class Library is in a namespace called RootNamespace
The above line would be placed at the top of your code file, in this case I'm assuming it's in Login.cs. This will be among the other using statements like using System; and you will be able to use the public static members of Library inside your Login class.
I would recommend using something other than global variables though, such as properties so that you can encapsulate some logic and protect against invalid states by running some validation before these values are changed.
Imagine the following scenario in a Xamarin solution:
Assembly A (PCL):
public abstract class MyBaseClass
{
public MyBaseClass()
{
[...]
}
[...]
}
Assembly B (3rd Party Library):
public class SomeLibClass
{
[...]
public void MethodThatCreatesClass(Type classType){
[...]
//I want to allow this to work
var obj = Activator.CreateInstance(classType);
[...]
}
[...]
}
Assembly C (Main project):
public class ClassImplA:MyBaseClass{
[...]
}
public class ClassImplA:MyBaseClass{
[...]
}
public class TheProblem{
public void AnExample(){
[...]
//I want to block these instantiations for this Assembly and any other with subclasses of MyBaseClass
var obj1 = new ClassImplA()
var obj2 = new ClassImplB()
[...]
}
}
How can I prevent the subclasses from being instantiated on their own assembly and allow them only on the super class and the 3rd Party Library (using Activator.CreateInstance)?
Attempt 1
I though I could make the base class with an internal constructor but then, I saw how silly that was because the subclasses wouldn't be able to inherit the constructor and so they wouldn't be able to inherit from the superclass.
Attempt 2
I tried using Assembly.GetCallingAssembly on the base class, but that is not available on PCL projects. The solution I found was to call it through reflection but it also didn't work since the result of that on the base class would be the Assembly C for both cases (and I think that's because who calls the constructor of MyBaseClass is indeed the default constructors of ClassImplA and ClassImplB for both cases).
Any other idea of how to do this? Or am I missing something here?
Update
The idea is to have the the PCL assembly abstract the main project (and some other projects) from offline synchronization.
Given that, my PCL uses its own DB for caching and what I want is to provide only a single instance for each record of the DB (so that when a property changes, all assigned variables will have that value and I can ensure that since no one on the main project will be able to create those classes and they will be provided to the variables by a manager class which will handle the single instantions).
Since I'm using SQLite-net for that and since it requires each instance to have an empty constructor, I need a way to only allow the SQLite and the PCL assemblies to create those subclasses declared on the main project(s) assembly(ies)
Update 2
I have no problem if the solution to this can be bypassed with Reflection because my main focus is to prevent people of doing new ClassImplA on the main project by simple mistake. However if possible I would like to have that so that stuff like JsonConvert.DeserializeObject<ClassImplA> would in fact fail with an exception.
I may be wrong but none of the access modifiers will allow you to express such constraints - they restrict what other entities can see, but once they see it, they can use it.
You may try to use StackTrace class inside the base class's constructor to check who is calling it:
public class Base
{
public Base()
{
Console.WriteLine(
new StackTrace()
.GetFrame(1)
.GetMethod()
.DeclaringType
.Assembly
.FullName);
}
}
public class Derived : Base
{
public Derived() { }
}
With a bit of special cases handling it will probably work with Activator class , but isn't the best solution for obvious reasons (reflection, error-prone string/assembly handling).
Or you may use some dependency that is required to do anything of substance, and that dependency can only be provided by your main assembly:
public interface ICritical
{
// Required to do any real job
IntPtr CriticalHandle { get; }
}
public class Base
{
public Base(ICritical critical)
{
if (!(critical is MyOnlyTrueImplementation))
throw ...
}
}
public class Derived : Base
{
// They can't have a constructor without ICritical and you can check that you are getting you own ICritical implementation.
public Derived(ICritical critical) : base(critical)
{ }
}
Well, other assemblies may provide their implementations of ICritical, but yours is the only one that will do any good.
Don't try to prevent entity creation - make it impossible to use entities created in improper way.
Assuming that you can control all classes that produce and consume such entities, you can make sure that only properly created entities can be used.
It can be a primitive entity tracking mechanism, or even some dynamic proxy wrapping
public class Context : IDisposable
{
private HashSet<Object> _entities;
public TEntity Create<TEntity>()
{
var entity = ThirdPartyLib.Create(typeof(TEntity));
_entities.Add(entity);
return entity;
}
public void Save<TEntity>(TEntity entity)
{
if (!_entities.Contains(entity))
throw new InvalidOperationException();
...;
}
}
It won't help to prevent all errors, but any attempt to persist "illegal" entities will blow up in the face, clearly indicating that one is doing something wrong.
Just document it as a system particularity and leave it as it is.
One can't always create a non-leaky abstraction (actually one basically never can). And in this case it seems that solving this problem is either nontrivial, or bad for performance, or both at the same time.
So instead of brooding on those issues, we can just document that all entities should be created through the special classes. Directly instantiated objects are not guaranteed to work correctly with the rest of the system.
It may look bad, but take, for example, Entity Framework with its gotchas in Lazy-Loading, proxy objects, detached entities and so on. And that is a well-known mature library.
I don't argue that you shouldn't try something better, but that is still an option you can always resort to.
I’m very new to programming. Actually less than one month back, I couldn’t name even 3 programming languages. So I’m really new to this.
After I understood the class concept and the object concept in OOP in general, I then realised that every single item present in the whole program is either an object or a class ready to give off objects.
Classes are non other than descriptions of objects, which are the main and sole players.
Moreover, functions or method are non other than sort of behavioural manifestation of an existing object.
( I wonder if the code line that we write for a function to be executed, the line of code in itself is a new object that refers to the existing original object that will perform the function we want , as part of its behaviour )
Now, If what I mentioned was near to be correct, What confused me next in my journey to understand OOP as a world wherein every single item is an object being utilised or destroyed, or brought into existence out of a class (blueprint ), which is nothing but a modifiable written description for objects how to be born.
What confused me here is the nature of “system”, “console”, and “namespace” each one of these, is it an object, so that we can call and utilise it without instantiating, or they are special classes readily instantiated as the program runs, or just ordinary classes ( which contradicts everything I understood ), because I can see "system" and "console" called and utilised only, and never instantiated ( just like an object )
Now, namespace seems to be a class that is instantiated into an object in the written script: ( namespace "the application name" { } ) but neither "system" nor "console" seems to be instantiated by programmer!
System is a namespace, Console is a static class inside the namespace System.
Static classes are classes which do not need to be created with the new keyword, and there is only one instance per application (excluding templated static classes - which you don't need to worry about for the moment)
Console can be written like this:
namespace System { //Namespace defined here!
public static class Console { //Static class defined here!
public static void WriteLine() { //Static method defined here!
//Implementation goes here
}
}
}
Note the keyword static when declaring the class. Removing this keyword would turn it into a normal class, and you'd have to use it like this:
var console = new System.Console();
console.WriteLine();
Based on the comments from Bauss and Physician about static methods.
You can write this, as well:
public class MyClass
{
public static void DoSomethingStatically()
{
}
public void DoSomethingNormally()
{
}
}
Now, you can do this:
MyClass.DoSomethingStatically();
but you cannot do:
MyClass.DoSomethingNormally();
To use the second method, you must create an instance:
var myClass = new MyClass();
myClass.DoSomethingNormally();
Note:
You cannot call a static method on an instance, so it is invalid to do the following:
var myClass = new MyClass();
myClass.DoSomethingStatically();
You can think of namespaces as containers of classes. System is a namespace which contains the Console class. Console is a special kind of class called a static class. A static class is denoted by the static keyword. The Console class's declaration would look something like this:
namespace System {
public static class Console {
//lots of stuff...
}
}
Actually you can read the Console class's source code in http://referencesource.microsoft.com
A static class cannot be instantiated. It just does its own work. It doesn't have objects. One of reasons is that it doesn't make sense to have objects. For example, the Math class is a static class because it doesn't make sense to say "Let's create a Math object!". Because Math is not like Cows or Streams or BinaryFormatters, which all are non static classes Generally, anything that you can prefix with "a" is not static. "a Stream", "a BinaryFormatter" etc.
Now for the namespace concept. You know sometimes the same word may mean different stuff depending on the context. e.g. Stream, in a programming context it means a file stream or some other kind of streams. But in a casual conversation, you say stream to mean a stream of water or something like that. So now you have to create two stream classes but there's a name conflict! That's why we have namespaces. Let's look at a real example. There are at least 2 classes called Path, but they are in different namespaces so it's ok to have the same name. One is in the System.Drawing namespace and the other is in the System.IO namespace. We often refer to those two classes as "System.IO.Path" and "System.Drawing.Path". Or you can write using directives.
Conclusion:
Both System and Console are not objects. They are a namespace and a static class respectively. And the word namespace denotes a namespace so it's not an object either.
I'm organizing a library project and I have a central manager class named Scenegraph and a whole bunch of other classes that live in the Scenegraph namespace.
What I'd really like is for the scenegraph to be MyLib.Scenegraph and the other classes to be MyLib.Scenegraph.*, but it seems the only way to do that would be to make all the other classes inner classes of Scenegraph in the Scenegraph.cs file and that's just too unwieldy.
Instead, I've organized it as Mylib.Scenegraph.Scenegraph and MyLib.Scenegraph.*, which sort of works but I find Visual Studio gets confused under some conditions as to whether I am referring to the class or the namespace.
Is there a good way to organize this package so it's convenient for users without glomming all my code together in an unmaintainable mess?
I don't recommend you to name a class like its namespace, see this article.
The Framework Design Guidelines say in section 3.4 “do not use the
same name for a namespace and a type in that namespace”. That is:
namespace MyContainers.List
{
public class List { … }
}
Why is this badness? Oh, let me count the ways.
You can get yourself into situations where you think you are referring
to one thing but in fact are referring to something else. Suppose you
end up in this unfortunate situation: you are writing Blah.DLL and
importing Foo.DLL and Bar.DLL, which, unfortunately, both have a type
called Foo:
// Foo.DLL:
namespace Foo { public class Foo { } }
// Bar.DLL:
namespace Bar { public class Foo { } }
// Blah.DLL:
namespace Blah
{
using Foo;
using Bar;
class C { Foo foo; }
}
The compiler gives an error. “Foo” is ambiguous between Foo.Foo and
Bar.Foo. Bummer. I guess I’ll fix that by fully qualifying the name:
class C { Foo.Foo foo; }
This now gives the ambiguity error “Foo in
Foo.Foo is ambiguous between Foo.Foo and Bar.Foo”. We still don’t know
what the first Foo refers to, and until we can figure that out, we
don’t even bother to try to figure out what the second one refers to.
Giving the same name to the namespace and the class can confuse the compiler as others have said.
How to name it then?
If the namespace has multiple classes then find a name that defines all those classes.
If the namespace has just one class (and hence the temptation to give it the same name) name the namespace ClassNameNS. This is how Microsoft names their namespaces at least.
Even though I agree with other answers in that you should not name your class the same as your namespace there are times in which you cannot comply with such requirements.
In my case for example I was not the person making such a decision therefore I needed to find a way to make it work.
So for those who cannot change namespace name nor class name here is a way in which you can make your code work.
// Foo.DLL:
namespace Foo { public class Foo { } }
// Bar.DLL:
namespace Bar { public class Foo { } }
// Blah.DLL:
namespace Blah
{
using FooNSAlias = Foo;//alias
using BarNSAlias = Bar;//alias
class C { FooNSAlias.Foo foo; }//use alias to fully qualify class name
}
Basically I created namespace "aliases" and that allowed me to fully qualify the class and the Visual Studio "confusion" went away.
NOTE:
You should avoid this naming conflict if it is under your control to do so.
You should only use the mentioned technique when you are not in control of the classes and namespaces in question.
I would suggest that you follow the advice I got on microsoft.public.dotnet.languages.csharp to use MyLib.ScenegraphUtil.Scenegraph and MyLib.ScenegraphUtil.*.
As others have said, it's a good practice to avoid naming a class the same as its namespace.
Here are some additional naming suggestions from an answer by svick to a related question "Same class and namespace name" on the Software Engineering Stack Exchange:
You're right that you shouldn't name the namespace the same as a type
it contains. I think there are several approaches you can use:
Pluralize: Model.DataSources.DataSource
This works especially well if the primary purpose of the namespace is
to contain types that inherit from the same base type or implement the
same interface.
Shorten: Model.QueryStorage
If a namespace contains only a small number of types, maybe you don't
need that namespace at all.
Make enterprisey: Model.ProjectSystem.Project
This can work especially for features that are important part of your
product, so they deserve their own name.
It happens when it's the main class of the namespace. So it's one motivation to put the namespace in a library, then the issue goes away if you add 'Lib' to the namespace name...
namespace SocketLib
{
class Socket
{
CA1724: Type Names Should Not Match Namespaces ...
Basically, if you follow Code Analysis for proper coding this rule says to not do what you are trying to do. Code Analysis is very useful in helping you find potential issues.
Old post, but here I go with another idea that may help someone:
"...but it seems the only way to do that would be to make all the other classes inner classes of Scenegraph in the Scenegraph.cs file and that's just too unwieldy."
This is really the better implementation for a bunch of scenarios. But, I do agree that having all that code on the same .cs file is annoying (to say the least).
You could solve it by making the base class a "partial class" and then, go on creating the inner classes on their own files (just remember that they'll have to declare the base class complement and then go on with the specific inner class for that file).
Something like...
Scenegraph.cs:
namespace MyLib
{
public partial class Scenegraph
{
//Scenegraph specific implementations
}
}
DependentClass.cs:
namespace MyLib
{
public partial class Scenegraph
{
public class DependentClass
{
//DependentClass specific implementations
}
}
}
I do think that this is the closer that you can get to having the clean implementation of inner classes while not having to clutter everything inside one huge and messy file.
Just Adding my 2 cents:
I had the following class:
namespace Foo {
public struct Bar {
}
public class Foo {
//no method or member named "Bar"
}
}
The client was written like this:
using Foo;
public class Blah {
public void GetFoo( out Foo.Bar[] barArray ) {
}
}
Forgiving the error GetFoo not returning the output instead of using the out parameter, the compiler could not resolve the data type Foo.Bar[] . It was returning the error: could not find type or namespace Foo.Bar .
It appears that when it tries to compile it resolved Foo as the class and did not find an embedded class Bar in the class Foo. It also could not find a namespace called Foo.Bar . It failed to look for a class Bar in the namespace Foo. The dots in a name space are NOT syntactic. The whole string is a token, not the words delimited by the dots.
This behaviour was exhibited by VS 2015 running .Net 4.6
I have a class:
public class MyClass {
private List<string> folderList;
// .... a lot of useful public methods here.....
}
Everything is fine. The list of folders is encapsulated, the class is accessible through public methods. OK. Now I need an "options" form that allows a user to choose folders for MyClass. There is a catch: new Setup class must have access to private folderList field (or I have to provide public methods to get and set the folder list - it's essentially the same). In old good C++ I would use 'friend' feature because nobody but Setup class may access folderList. But there is no 'friend' feature in C# (I'm a newbie in the C# world).
P.S. Actually I just made folderList public, but I feel there is a better solution.
Thanks.
You can use "internal" keyword to make your method available only within your assembly/project and if you want to access your internal methods in other project or assembly then you can use "InternalsVisibleTo" attribute, where you can access your internals only in that assembly for which you define this attribute.
MSDN Internal Keyword
I believe the keyword you're looking for is internal. It is loosely equivilent to C++'s friend.
Internal provides assembly-level visibility.
Paired with Femaref's suggestion of using a Property, and you should have your full solution.
I am not sure if this is what he/she wanted. He/she did not put the requirement that the potential client will be in current assembly... Accordingly, when using friend in c++ (which was never considered a good style) you must know the exact type of the class which will be entitled to access the member. If this class is not part of the program you are writing, you cannot grant access this way.
If you want conditional access to some property or method of an instance of a class, you will need to implement some kind of entitlement mechanism, for example:
public IList<Folder> GetFolderList(Object pClient, IEntitlementService pService) {
if (pService.IsEntitledToAccess(this, pClient) {
return folderList;
} else {
throw new AccessNotGrantedException("...");
}
}
I believe there are built-in utilities in the .Net framwork for that purpose, just go and google (or bing)...
As an exact answer to the question I would suggest the following - create a separate interface IFolderList:
interface IFolderList
{
IList<string> FolderList { get; }
...
}
Well, you can add other required members to interface
In the class MyClass implement this interface explicitly.
As a result, the class Setup can gain access to data through an explicit cast to an interface IFolderList or work only with these interface.
An alternative to making an internal method to be used by your Setup class would be to use the Visitor pattern and add a method that takes a Setup class instance as a parameter, then uses the private folderList to initialize/change Setup state as required. Of course that would require the appropriate public methods on the Setup class, so might not fit your needs.
Making folderList field public is the worst case. Exposing implementation details through public fields or through poorly designed public property (there are no differences for collections between public fields and public property with getter and setter).
With public fields you can't promote a field to be a property when you want to add validation, change notification, put it into an interface or change your collection type from one type to another.
BTW, Jeffrey Richter in annotation to Framework Design Guideline mentioned that "Personally, I always make my fields private. I don't even expose fields as internal, because doing so would give me no protection from code in my own assembly"
I think the best way to add explicit interface that expose strict abstraction to MyClass clients.
For example, you may add two separate methods to retrieving folders and to adding new folder to this storage:
class MyClass {
//You should return IList<string>
public IList<string> MyList {get {return myList;} }
//Or even IEnumerable<string>, because you should return
//as minimal interface as your clients needs
public IEnumerable<string> MyList {get {return myList;} }
//You may expose this functionality through internal
//method, or through protected internal method,
//but you should avoid direct access to your implementation
//even for descendants or another classes in your assembly
public void AddElement(string s) {myList.Add(s);}
private List<string> myList;
}
That's what properties are for in C#:
public class MyClass
{
private List folderList;
public List FolderList
{
get {return folderList;}
set {folderList = value;}
}
}
Properties encapsulate the private fields, provide possibilites for validation while setting. Also, you should read up on Generics (abit like templates in c++) and use List<T> instead of List to have a strongly typed collection.
However, you probably wont be able to achieve what you plan unless Setup derives from MyClass. In that case, you can use a protected field.