I have heard some people are against the use of internal modifier to hide classes and members from outside the assembly in which they are declared because it defeats the main principles of OOP. Is this really true?
Is this really true?
No, it is not true. Internal visibility modifier has its usages. There are classes which you don't want to be used outside of their containing assembly but still to be public inside the assembly. For example if you are designing an API, there might be classes that you don't want to expose to consumers of your API.
internal keyword allows developers to hide members of the assembly if it is used by another assembly. In .NET framework for example there are many types that are internal, meaning they are only required for the inner assembly usage and are not visible from outside the library. This is encapsulation on the assembly level.
Well people are free to have their opinions. I'm not sure how "internal" defeats the main principles of OOP.. perhaps a link would help me to evaluate their stance.
I use internal to hide types that I don't want anyone outside the assembly to use. This is pro-OOP in my opinion
expose behavior but hide implementation.
use the most restrictive access possible
e.g. I refactor some common code out of 2 public types ; this new type starts out as internal. Unless some client/test drives me to increase the visibility. Also I sometimes use it as a temp cheat to avoid writing tests for some types (all public types should have tests). It has served me well.
Related
I have a very simple utility program I have built in C#. It only has one namespace and one class. I am just wondering what the best practice is in regards to adding accessibility keywords to the methods/variables in this context. Is it okay to just leave the accessibility keyword out here? It seems to me that adding one will be unproductive, but the methods just feels so "naked" without one.
Best Practice is usually quoted as this:
Make everything as restrictive as possible and only unrestrict when neccessary
The defaults are this in C#
classes: internal
class members: private
Private classes unless nested are rarely useful, but never mind that.
Now the last bit is my opinion. Code readability and ease of understanding is sooooo important and so I would say that it best to explicitly put the access levels in even if they are the same as the default
Leaving them out is the same as whatever the most restrictive possible is (so private for within a class and internal for a class itself within a namespace).
Technically it makes no difference whether you explicitly write private or leave it out. As a matter of convention it's more common to be explicit (include the private) and it's good to get into the habit of following common convention, so worth doing for that matter alone.
Leaving off an access modifier when declaring a code element means the compiler will provide a default access level. In your case, the class (a top-level type) would be internal and its members would be private. This is suitable for a standalone utility which you do not expect to be referenced by any other code (internal means "only this assembly (EXE/DLL) can see this" and private means "only the class/struct that declares this can see this"). Whether you want to include or leave off the keywords is a matter of style.
Mark them as they would be used if they were in a larger application.
You never know when you might migrate this code into a larger app.
Also, 6 or 7 letters to be explicit and not have yourself or someone else later on wondering what your intentions were seems a small price to pay
I was reading OOPs Concepts from internet using articles.
In one of article, I have read following about abstraction:
If we have a method named "CalculatePrice" inside the "Billing" class,
we are not concerned about the calculations inside the
"CalculatePrice" method. We just pass the necessary parameters and get
the output. We hide the implementation of "Calculate Price".
so my question is : In C#, we are using dlls and namespace and calls the specific methods. can we say that, dlls and namespaces are the concept of Abstractions ??
Thanks
No.
You should generally just think of dll-files and namespaces as ways to organize your projects.
The abstraction of CalculatePrice consists simply of the "hiding" of it's logic inside the method. When another piece of code calls the method, it does not care what happens inside it - it is only interested in the result.
Abstractions in C# (and .Net in general) are made using things like Classes, Interfaces, Abstract Classes, and method and properties that are defined and/or implemented in these.
Your focus should be on these concepts, and on how they are used together in different "patterns" to solve various types of problems.
To expand just a little on your example: If CalculatePrice was defined in an interface, then calling code would "talk to" that interface, without caring about what was behind it. An implementation of that interface - the code that actually performs the logic - could be anything. It could change, and keep changing, as long as it fulfills the requirements (the "contract") defined in the interface, since that would allow the calling code to keep using it.. and that is how abstraction works in C#.
Interesting that there are four answers all saying "no". In reality, the answer is "sometimes". If the implementation of CalculatePrice relies on another class, which is marked as internal, then its assembly does form part of the abstraction, since internal classes are only accessible to other classes in that assembly.
Namespaces in .NET do not form part of any abstraction though. In other languages they can, as internal can be tied to namespaces, but that is not how .NET languages work.
Such information hiding is the most basic form of abstraction though. C#'s most powerful abstraction tools are interfaces, support for dependency injection and its treatment of methods as values. If you are interested in understanding more about abstraction in C#, they are the three areas to focus on.
so my question is : In C#, we are using dlls and namespace and calls the specific methods. can we say that, dlls and namespaces are the concept of Abstractions ??
No.
I have 2 forms and 1 Class.
I made the class a Static Class.
It has two methods with public modifiers.
Ex: Public string PrintHello(), Public void Task1()
I want these methods to be accessible from both Form1 and Form2.
I understand that using "Public" modifier is not good, so I've looked at "Internal" modifier and it seems to do the job.
Basically, I want to create a secure way of accessing my class.
What would be the best way of doing so and could you provide an example of how to do so ?
Thank you
Access modifiers does not provide security to you code.
Is someone really wants to use your privet methods he can use ILDASM to de-compile your code and use them, that would be just one example of many.
Access modifiers are there to to allow you to program using with an Object Oriented code design.
In general:
Private modifiers are internal to your class implementation and other classes or layers of your code dose not NEED nor want to know about there existence.
Internal modifiers are there to provide additional functionality required for the whole assembly but again they are not required for any one else (outside of the assembly) because they are implementation specific.
And finally Public modifiers are used to define the interface of your class with the outside world, these are methods and properties that should and will be used by any one that requires some sor of functionality from your code.
Depends on where you think the code that calls this methods will likely live. If it is only going to be ever called from the class that defined this method, then it should be private. If you only want to call it from the same assembly (dll) but you don't want to call the methods from other dlls, then you should make it internal. This way you can ship your dll to other projects and you don't have to worry about supporting your methods (because they won't have access to your methods).
But if you are doing a general purpose libarary/dll etc. Then the methods should be public.
It all depends on who or what you think is going to call your methods.
In a single project (ie assembly) is the internal attribute any different from the public attribute?
I don't see a difference, but I wanted to make sure there are no edge cases I am not thinking of.
Yes, the difference comes in when somebody else is referencing your assembly. In that case only the public members will be visible. But don't forget, the internal/private members can still be accessed via Reflection/dynamics. Also it will no longer be labeled with the BindingFlags.Public, it uses BindingFlags.NonPublic instead.
Yes, it's the same. Internal is public within the same assembly so if you have a single assembly there is no difference
Lots of people are saying yes, but the answer really is no.
If somebody references your assembly then there is a very big difference!
In general, yes.
In very rare cases, there may be differences, especially in reflection-specific contexts. For example, Activator.CreateInstance(typeof(myType)) will succeed if the type has a public parameterless constructor, but may not if the type only has an internal one (atleast on .NET 3.5) - you will have to call the overload with nonpublic = true.
Also, note that interface implementations are always public. Consequently, Replace all -> "public" - "internal" from your editor may produce code that does not compile - the compiler will refuse to allow you to implement an interface's member with internal visibility.
From with the assembly in which it is declared it is the same.
Yes, basically internal means that classes can be only used inside your assembly, which will work the same way as public inside the assembly.
But if you think your assembly will be used by any projects, its better to use public on the classes that can be referenced.
Also if you declare a class as internal, and some method inside public, internal will override its accessibility, making it internal.
What should go into the top level namespace? For example, if I have MyAPI.WebLogic, MyAPI.Compression, etc. If I put classes into the top level namespace, am I violating the principle of encapsulation?
Namespaces are not for OOP related concepts like encapsulation. There for organization, so organize it in a way that what makes sense to your application. Most the work I do on websites has a business library and most often it's all tucked under a single namespace.
Depends what the classes are.
One guideline I try to follow is that dependencies between namespaces shouldn't follow a cycle. In other words, low-level namespaces can't access types from higher-level namespaces.
This means that the top-level MyAPI namespace must contain either:
High-level code: code that's allowed to look inside MyAPI.WebLogic and MyAPI.Compression
Or, low-level code: code that's used by MyAPI.WebLogic and/or MyAPI.Compression
Patrick Smacchia has written a lot on the advantages of structuring your code in this way, including on this site: Detecting dependencies between namespaces in .NET
Depends on what the namespace is for really. If its an application then perhaps something like bootstrapper classes, loaders etx, Main's etc. I'd say (as with everything) "it depends".
I don't think you're really violating encapsulation per se by doing that.
Normally namespaces are just a way to organize your classes to make them easier to find, so whatever makes sense for your app.
You're not violating encapsulation at all as far as I see it. In fact, I'm not even sure this can be called encapsulation, given that namespaces aren't specific to OOP - its rather just the orginsation of types.
The rule is simply to place a type in the top-level namespace if you feel it belongs there. An obvious example for this situation is when (using your examples) MyAPI.WebLogic and MyAPI.Compression (perhaps as well as others) all need to utilise a certain type - it is therefore best just to put this type in MyAPI. If you're still not quite sure what belongs, use the Microsoft libraries as examples. There are plenty of classes in the System namespace within the BCL!