Default visibility for C# classes and members (fields, methods, etc.)? - c#

I'm trying to find a reference for the default visibility of various aspects of C#. Class types, fields, methods, enums, etc.
Can someone provide a list of these along with their default visibility (i.e., no prefixed modifier)?

All of the information you are looking for can be found here and here (thanks Reed Copsey):
From the first link:
Classes and structs that are declared directly within a namespace (in other words, that are not nested within other classes or structs) can be either public or internal. Internal is the default if no access modifier is specified.
...
The access level for class members and struct members, including nested classes and structs, is private by default.
...
interfaces default to internal access.
...
Delegates behave like classes and structs. By default, they have internal access when declared directly within a namespace, and private access when nested.
From the second link:
Top-level types, which are not nested in other types, can only have internal or public accessibility. The default accessibility for these types is internal.
And for nested types:
Members of Default member accessibility
---------- ----------------------------
enum public
class private
interface public
struct private

From MSDN:
Top-level types, which are not nested in other types, can only have internal or public accessibility. The default accessibility for these types is internal.
Nested types, which are members of other types, can have declared accessibilities as indicated in the following table.
Members of
Default member accessibility
Allowed declared accessibility of the member
enum
public
None
class
private
publicprotectedinternalprivateprotected internalprivate protected
interface
public
publicprotectedinternalprivate*protected internalprivate protected
struct
private
publicinternalprivate
* An interface member with private accessibility must have a default implementation.
Source: Accessibility Levels (C# Reference) (September 15th, 2021)

By default, the access modifier for a class is internal. That means to say, a class is accessible within the same assembly. But if we want the class to be accessed from other assemblies then it has to be made public.

By default is private. Unless they're nested, classes are internal.

Related

Access private classes in a class library, from a console app c# [duplicate]

What is the default access modifier for classes, methods, members, constructors, delegates and interfaces?
The default access for everything in C# is "the most restricted access you could declare for that member".
So for example:
namespace MyCompany
{
class Outer
{
void Foo() {}
class Inner {}
}
}
is equivalent to
namespace MyCompany
{
internal class Outer
{
private void Foo() {}
private class Inner {}
}
}
The one sort of exception to this is making one part of a property (usually the setter) more restricted than the declared accessibility of the property itself:
public string Name
{
get { ... }
private set { ... } // This isn't the default, have to do it explicitly
}
This is what the C# 3.0 specification has to say (section 3.5.1):
Depending on the context in which a
member declaration takes place, only
certain types of declared
accessibility are permitted.
Furthermore, when a member declaration
does not include any access modifiers,
the context in which the declaration
takes place determines the default
declared accessibility.
Namespaces implicitly have public declared accessibility. No access
modifiers are allowed on namespace
declarations.
Types declared in compilation units or namespaces can have public or
internal declared accessibility and
default to internal declared
accessibility.
Class members can have any of the five kinds of declared accessibility
and default to private declared
accessibility. (Note that a type
declared as a member of a class can
have any of the five kinds of declared
accessibility, whereas a type declared
as a member of a namespace can have
only public or internal declared
accessibility.)
Struct members can have public, internal, or private declared
accessibility and default to private
declared accessibility because structs
are implicitly sealed. Struct members
introduced in a struct (that is, not
inherited by that struct) cannot have
protected or protected internal
declared accessibility. (Note that a
type declared as a member of a struct
can have public, internal, or private
declared accessibility, whereas a type
declared as a member of a namespace
can have only public or internal
declared accessibility.)
Interface members implicitly have public declared accessibility. No
access modifiers are allowed on
interface member declarations.
Enumeration members implicitly have public declared accessibility. No
access modifiers are allowed on
enumeration member declarations.
(Note that nested types would come under the "class members" or "struct members" parts - and therefore default to private visibility.)
top level class: internal
method: private
members (unless an interface or enum): private (including nested classes)
members (of interface or enum): public
constructor: private (note that if no constructor is explicitly defined, a public default constructor will be automatically defined)
delegate: internal
interface: internal
explicitly implemented interface member: public!
Short answer: minimum possible access (cf Jon Skeet's answer).
Long answer:
Non-nested types, enumeration and delegate accessibilities (may only have internal or public accessibility)
| Default | Permitted declared accessibilities
------------------------------------------------------------------
namespace | public | none (always implicitly public)
enum | public | public, internal
interface | internal | public, internal
class | internal | public, internal
struct | internal | public, internal
delegate | internal | public, internal
Nested type and member accessiblities
| Default | Permitted declared accessibilities
------------------------------------------------------------------
namespace | public | none (always implicitly public)
enum | public | All¹
interface | public | All¹
class | private | All¹
struct | private | public, internal, private²
delegate | private | All¹
constructor | private | All¹
enum member | public | none (always implicitly public)
interface member | public | none (always implicitly public)
method | private | All¹
field | private | All¹
user-defined operator| none | public (must be declared public)
¹ All === public, protected, internal, private, protected internal
² structs cannot inherit from structs or classes (although they can, interfaces), hence protected is not a valid modifier
The accessibility of a nested type depends on its accessibility domain, which is determined by both the declared accessibility of the member and the accessibility domain of the immediately containing type. However, the accessibility domain of a nested type cannot exceed that of the containing type.
Note: CIL also has the provision for protected and internal (as opposed to the existing protected "or" internal), but to my knowledge this is not currently available for use in C#.
See:
http://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx
http://msdn.microsoft.com/en-us/library/ms173121.aspx
http://msdn.microsoft.com/en-us/library/cx03xt0t.aspx
(Man I love Microsoft URLs...)
Have a look at Access Modifiers (C# Programming Guide)
Class and Struct Accessibility
Classes and structs that are declared directly within a namespace (in other words, that are not nested within other classes or structs) can be either public or internal. Internal is the default if no access modifier is specified.
Struct members, including nested classes and structs, can be declared as public, internal, or private. Class members, including nested classes and structs, can be public, protected internal, protected, internal, private protected or private. The access level for class members and struct members, including nested classes and structs, is private by default. Private nested types are not accessible from outside the containing type.
Derived classes cannot have greater accessibility than their base types. In other words, you cannot have a public class B that derives from an internal class A. If this were allowed, it would have the effect of making A public, because all protected or internal members of A are accessible from the derived class.
You can enable specific other assemblies to access your internal types by using the InternalsVisibleToAttribute. For more information, see Friend Assemblies.
Class and Struct Member Accessibility
Class members (including nested classes and structs) can be declared with any of the six types of access. Struct members cannot be declared as protected because structs do not support inheritance.
Normally, the accessibility of a member is not greater than the accessibility of the type that contains it. However, a public member of an internal class might be accessible from outside the assembly if the member implements interface methods or overrides virtual methods that are defined in a public base class.
The type of any member that is a field, property, or event must be at least as accessible as the member itself. Similarly, the return type and the parameter types of any member that is a method, indexer, or delegate must be at least as accessible as the member itself. For example, you cannot have a public method M that returns a class C unless C is also public. Likewise, you cannot have a protected property of type A if A is declared as private.
User-defined operators must always be declared as public and static. For more information, see Operator overloading.
Finalizers cannot have accessibility modifiers.
Other Types
Interfaces declared directly within a namespace can be declared as public or internal and, just like classes and structs, interfaces default to internal access. Interface members are always public because the purpose of an interface is to enable other types to access a class or struct. No access modifiers can be applied to interface members.
Enumeration members are always public, and no access modifiers can be applied.
Delegates behave like classes and structs. By default, they have internal access when declared directly within a namespace, and private access when nested.
Class is Internal by default.
Class members are private by default.
Interface is Internal by default.
Interface members are public by default. (Interfaces won't allow
us to specify any kind of accessibility to it's members.)
Note: If you try to specify any access specifier to interface's members then, it shows compile error.
Struct is Internal by default.
Struct members are private by default.
I would like to add some documentation link. Check out more detail here.
Simplest answer is the following.....
All members in C# always take the LEAST accessible modifier possible by default.
That is why all top level classes in an assembly are "internal" by default, which means they are public to the assembly they are in, but private or excluded from access to outside assemblies. The only other option for a top level class is public which is more accessible. For nested types its all private except for a few rare exceptions like members of enums and interfaces which can only be public. Some examples. In the case of top level classes and interfaces, the defaults are:
class Animal same as internal class Animal
interface Animal same as public interface Animal
In the case of nested classes and interfaces (inside types), the defaults are:
class Animal same as private class Animal
interface Animal same as private interface Animal
If you just assume the default on c# types is always the most private, then you do not need to use custom accessors until you need to change the default. They are secure out of the box!
Namespace level: internal
Type level: private
internal is default access modifier for class.
private is default access modifier for class members.
Internal is the default modifier

Can an interface have static variables in C#

It might be a silly question, I appreciate if someone can help me understand it.
Can an interface in C# can have static variables?
If the interface itself need to be static to declare static variables inside?
How the implementation goes for static variables(Or say property) within an interface, when we implement in a class?
Some examples and perspicuous explanation would be greatly appreciated.
No, an interface in C# can't declare fields at all. You can't declare a static interface at all in C#, nor can you declare static members within an interface.
As per section 11.2 of the C# specification:
An interface declaration may declare zero or more members. The members of an interface must be methods, properties, events, or indexers. An interface cannot contain constants, fields, operators, instance constructors, destructors, or types, nor can an interface contain static members of any kind.
All interface members implicitly have public access. It is a compile-time error for interface member declarations to include any modifiers. In particular, interfaces members cannot be declared with the modifiers abstract, public, protected, internal, private, virtual, override, or static.
An interface is a contract, ie a description of the public instance methods and properties that any implementing class must provide.
Interfaces cannot specify any static methods or properties. They cannot specify internal, protected or private methods or properties. Nor can they specify fields.
1- No, because interface is not a class
2- Consider an Abstract class
3- Static Property in an interface is not defined nor is meaningful in C#

private class outside namespace

I want to create a class outside a namespace so that its default access modifier is 'PRIVATE'. I am doing like this:
namespace KnowStructs
{
class Clas1 {}
}
class MyClass {}
But still my class 'MyClass' is referred as Internal when I look in Reflector.
Can anyone help me out.
From Accessibility Levels:
Top-level types, which are not nested in other types, can only have internal or public accessibility. The default accessibility for these types is internal.
and:
Access modifiers are not allowed on namespaces. Namespaces have no access restrictions.
and for private:
Private members are accessible only within the body of the class or the struct in which they are declared
That is, the private keyword is explicitly defined in terms of a containing class or struct.
So whatever you're trying to do, I don't understand it. How could a top level private type possibly be useful? No other code would be able to reference it (in any way, even if it had e.g. static factory methods).
If a private class is allowed that is not a nested type then what would that mean? If it is more restrictive than internal then how would you use it or create an instance. Any use case will require it to be internal at a minimum. I would like to see how you intend to use it.
It simply makes no logical sense.
Whereas having a private nested class scopes itself to the parent containing class. If it were internal then you still will be able to make an instance within the assembly.
So for classes having no modifier is internal by default for non nested types and private for nested types as .Net always applies the most restrictive access when no modifier is specified.
You can make the class internal, if you only want to be accessible by classes in your namespace

In C#, what is the difference between public, private, protected, and having no access modifier?

All my college years I have been using public, and would like to know the difference between public, private, and protected?
Also what does static do as opposed to having nothing?
Access modifiers
From learn.microsoft.com:
public
The type or member can be accessed by any other code in the same assembly or another assembly that references it.
private
The type or member can only be accessed by code in the same class or struct.
protected
The type or member can only be accessed by code in the same class or struct, or in a derived class.
private protected (added in C# 7.2)
The type or member can only be accessed by code in the same class or struct, or in a derived class from the same assembly, but not from another assembly.
internal
The type or member can be accessed by any code in the same assembly, but not from another assembly.
protected internal
The type or member can be accessed by any code in the same assembly, or by any derived class in another assembly.
When no access modifier is set, a default access modifier is used. So there is always some form of access modifier even if it's not set.
static modifier
The static modifier on a class means that the class cannot be instantiated, and that all of its members are static. A static member has one version regardless of how many instances of its enclosing type are created.
A static class is basically the same as a non-static class, but there is one difference: a static class cannot be externally instantiated. In other words, you cannot use the new keyword to create a variable of the class type. Because there is no instance variable, you access the members of a static class by using the class name itself.
However, there is a such thing as a static constructor. Any class can have one of these, including static classes. They cannot be called directly & cannot have parameters (other than any type parameters on the class itself). A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced. Looks like this:
static class Foo()
{
static Foo()
{
Bar = "fubar";
}
public static string Bar { get; set; }
}
Static classes are often used as services, you can use them like so:
MyStaticClass.ServiceMethod(...);
A graphical overview (summary in a nutshell)
Actually, it's a little bit more complicated than that.
Now (as of C# 7.2), there's also private protected, and it matters whether a derived class is in the same assembly or not.
So the overview needs to be expanded:
See also the C#-dotnet-docs on the subject.
Since static classes are sealed, they cannot be inherited (except from Object), so the keyword protected is invalid on static classes.
For the defaults if you put no access modifier in front, see here:
Default visibility for C# classes and members (fields, methods, etc.)?
Non-nested
enum public
non-nested classes / structs internal
interfaces internal
delegates in namespace internal
class/struct member(s) private
delegates nested in class/struct private
Nested:
nested enum public
nested interface public
nested class private
nested struct private
Also, there is the sealed-keyword, which makes a class not-inheritable.
Also, in VB.NET, the keywords are sometimes different, so here a cheat-sheet:
Public - If you can see the class, then you can see the method
Private - If you are part of the class, then you can see the method, otherwise not.
Protected - Same as Private, plus all descendants can also see the method.
Static (class) - Remember the distinction between "Class" and "Object" ? Forget all that. They are the same with "static"... the class is the one-and-only instance of itself.
Static (method) - Whenever you use this method, it will have a frame of reference independent of the actual instance of the class it is part of.
Reposting the awesome diagrams from this answer.
Here are all access modifiers in Venn diagrams, from more limiting to more promiscuous:
private:
private protected: - added in C# 7.2
internal:
protected:
protected internal:
public:
Yet another visual approach of the current access modifier (C# 7.2). Hopefully the schema helps to remember it easier
(click the image for interactive view.)
Outside Inside
If you struggle to remember the two-worded access modifiers, remember outside-inside.
private protected: private outside (the same assembly) protected inside (same assembly)
protected internal: protected outside (the same assembly) internal inside (same assembly)
using System;
namespace ClassLibrary1
{
public class SameAssemblyBaseClass
{
public string publicVariable = "public";
protected string protectedVariable = "protected";
protected internal string protected_InternalVariable = "protected internal";
internal string internalVariable = "internal";
private string privateVariable = "private";
public void test()
{
// OK
Console.WriteLine(privateVariable);
// OK
Console.WriteLine(publicVariable);
// OK
Console.WriteLine(protectedVariable);
// OK
Console.WriteLine(internalVariable);
// OK
Console.WriteLine(protected_InternalVariable);
}
}
public class SameAssemblyDerivedClass : SameAssemblyBaseClass
{
public void test()
{
SameAssemblyDerivedClass p = new SameAssemblyDerivedClass();
// NOT OK
// Console.WriteLine(privateVariable);
// OK
Console.WriteLine(p.publicVariable);
// OK
Console.WriteLine(p.protectedVariable);
// OK
Console.WriteLine(p.internalVariable);
// OK
Console.WriteLine(p.protected_InternalVariable);
}
}
public class SameAssemblyDifferentClass
{
public SameAssemblyDifferentClass()
{
SameAssemblyBaseClass p = new SameAssemblyBaseClass();
// OK
Console.WriteLine(p.publicVariable);
// OK
Console.WriteLine(p.internalVariable);
// NOT OK
// Console.WriteLine(privateVariable);
// Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
//Console.WriteLine(p.protectedVariable);
// OK
Console.WriteLine(p.protected_InternalVariable);
}
}
}
using System;
using ClassLibrary1;
namespace ConsoleApplication4
{
class DifferentAssemblyClass
{
public DifferentAssemblyClass()
{
SameAssemblyBaseClass p = new SameAssemblyBaseClass();
// NOT OK
// Console.WriteLine(p.privateVariable);
// NOT OK
// Console.WriteLine(p.internalVariable);
// OK
Console.WriteLine(p.publicVariable);
// Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
// Console.WriteLine(p.protectedVariable);
// Error : 'ClassLibrary1.SameAssemblyBaseClass.protected_InternalVariable' is inaccessible due to its protection level
// Console.WriteLine(p.protected_InternalVariable);
}
}
class DifferentAssemblyDerivedClass : SameAssemblyBaseClass
{
static void Main(string[] args)
{
DifferentAssemblyDerivedClass p = new DifferentAssemblyDerivedClass();
// NOT OK
// Console.WriteLine(p.privateVariable);
// NOT OK
//Console.WriteLine(p.internalVariable);
// OK
Console.WriteLine(p.publicVariable);
// OK
Console.WriteLine(p.protectedVariable);
// OK
Console.WriteLine(p.protected_InternalVariable);
SameAssemblyDerivedClass dd = new SameAssemblyDerivedClass();
dd.test();
}
}
}
Regarding the question of Nothing
Namespace types are internal by default
Any type member, including nested types are private by default
public - can be access by anyone anywhere.
private - can only be accessed from with in the class it is a part of.
protected - can only be accessed from with in the class or any object that inherits off of the class.
Nothing is like null but in VB.
Static means you have one instance of that object, method for every instance of that class.
Hmm.
See here: Access Modifiers.
In a nutshell:
Public gives the method or type complete visibility from other types/classes.
Private allows only the type containing the private method/variable access to the private method/variable (note that nested classes also have access to the containing classes private methods/variables).
Protected is similar to private except derived classes can also access protected methods.
"Nothing" is VB.NET's equivalent to null. Although if you're referring to "nothing" meaning "no access modifier", then it depends, although a very rough rule of thumb (certainly in C#) is that if you don't explicitly specify an access modifier, the method/variable declaration is usually as restricted as it can be.
i.e.
public class MyClass
{
string s = "";
}
is effectively the same as:
public class MyClass
{
private string s = "";
}
The linked MSDN article will offer a fully description when there's no access modifier explicitly specified.
mmm...
Static means that you can access that function without having an instance of the class.
You can access directly from the class definition.
A status of Private indicates that variables can only be accessed by objects of the same class. Protected status extends that access to include descendants of the class as well.
"from the above table we can see the deference between private and protected... am think both are same ....so what the need for that two separate command"
Check MSDN link for more information
public means that it can be accessed by any class in any assembly, which includes the class itself.
protected internal means it can be accessed by the class itself (in the class definition), and it can be accessed by any class in the current assembly, but outside of the assembly it can only be accessed by a class that inherits the class, or by the class itself (if it is a partial class) – basically it means internal inside the assembly and protected outside of the assembly.
protected means it can only be accessed by the class itself, or accessed by a class that inherits it and that class can be in any assembly
internal means it can be accessed by the class itself or by any class in the assembly but can't be accessed at all outside of the assembly unless by the class itself (i.e. it is a partial class)
private protected means it can only be accessed by the class itself, or it can be accessed by a class that inherits it and only if that class is in the current assembly. Outside of the assembly, it can only be accessed by the class itself (i.e. it is a partial class) – basically combines internal and protected, or another way of putting it is it's private outside of the assembly and protected inside the assembly.
private means that it can only be accessed by the class itself
no access modifier: The default access for everything in C# is "the most restricted access you could declare for that member"., which is private for a member / method / nested class in a class and internal for a non-nested class.
In the above text 'accessed' means accessed via an object of the class type, which within a method of the class itself will be the implicit this object, or perhaps the method instantiates an explicit object of the current class type and accesses it through that object. Both are considered to be being accessed by the class itself and therefore the access rules are the same. This also applies to an access being performed from a static method, or when it is a static member / method being accessed, except the access is performed using the class scope and not and object. A member / method of a static class needs to be explicitly made static or it won't compile.
Classes that are not nested can either be public or internal and are internal by default. Classes that are nested can be any access type, and if the parent class is static, it does not need to be static and neither do its members. An internal class means that it can only be instantiated or its static members accessed from the current assembly.
You can have a public member / method / nested class in an internal or private nested class -- only the access specifier (in the fully qualified name of the access that is being made) that is below the level required in the current access that is being made prevents the access.
Inheritance in C# is always public unlike C++, which can privately or protectedly inherit, which then changes the access of all classes that then inherit from the class that is inheriting from this class, as well as the access via object / via class scope of type of the class that inheriting privately / protectedly from the class and the class that is inheriting from the class that is inheriting privately / protectedly form the class, and so on. The access is changed such that all access modifiers less restrictive than private or protected are made private and protected respectively.
Careful! Watch the accessibility of your classes. Public and protected classes and methods are by default accessible for everyone.
Also, Microsoft isn't very explicit in showing access modifiers (public, protected, etc.. keywords) when new classes in Visual Studio are created. So, take good care and think about the accessibility of your class because it's the door to your implementation internals.
Those access modifiers specify where your members are visible. You should probably read this up. Take the link given by IainMH as a starting point.
Static members are one per class and not one per instance.
I think it is related to good OOP design. If you are a developer of a library you want to hide the inner workings of your library. That way, you can modify your library inner workings later on. So you put your members and helper methods as private, and only interface methods are public. Methods that should be overwritten should be protected.
C# has, in total, 6 access modifiers:
private: The member declared with this accessibility can be visible within the containing type, it is not visible to any derived types, other types in the same assembly or types outside of the containing assembly. i.e., access is limited to the containing type only.
protected: The member declared with this accessibility can be visible within the types derived from the containing type within the containing assembly, and the types derived from the containing type outside of the containing assembly. i.e., access is limited to derived types of the containing type.
internal: The member declared with this accessibility can be visible within the assembly containing this member, it is not visible to any assembly outside of the containing assembly. i.e., access is limited to containing assembly only.
internal protected: The member declared with this accessibility can be visible within the types derived from the containing type within or outside of the containing assembly, it is also visible to any types within the containing assembly. i.e., access is limited to containing assembly or derived types.
public: The member declared with this accessibility can be visible within the assembly containing this member, or any other assembly that references the containing assembly. i.e., access is not limited.
In C# 7.2, a new level of accessibility was added:
private protected: The member declared with this accessibility can be visible within the types derived from this containing type within the containing assembly. It is not visible to any types not derived from the containing type, or outside of the containing assembly. i.e., the access is limited to derived types within the containing assembly.
Source including a sample code of the new private protected access modifier
public The type or member can be accessed by any other code in the same assembly or another assembly that references it. The accessibility level of public members of a type is controlled by the accessibility level of the type itself.
private The type or member can be accessed only by code in the same class or struct.
internal Internal types or members are accessible only within files in the same assembly.
protected The type or member can be accessed only by code in the same class, or in a class that is derived from that class.
internal: The type or member can be accessed by any code in the same assembly, but not from another assembly. In other words, internal types or members can be accessed from code that is part of the same compilation.
protected internal: The type or member can be accessed by any code in the assembly in which it's declared, or from within a derived class in another assembly.
private protected The type or member can be accessed by types derived from the class that are declared within its containing assembly.
protected internal A protected internal member is accessible from the current assembly or from types that are derived from the containing class.
static modifier is used to declare a static member, which belongs to the type itself rather than to a specific object. The static modifier can be used to declare static classes. In classes, interfaces, and structs, you may add the static modifier to fields, methods, properties, operators, events, and constructors.
With C# 11 you can also use the file access modifier.
The file modifier restricts a top-level type's scope and visibility to the file in which it's declared. The file modifier will generally be applied to types written by a source generator. File-local types provide source generators with a convenient way to avoid name collisions among generated types.
// In File1.cs:
file interface IWidget
{
int ProvideAnswer();
}
file class HiddenWidget
{
public int Work() => 42;
}
public class Widget : IWidget
{
public int ProvideAnswer()
{
var worker = new HiddenWidget();
return worker.Work();
}
}
I have created another type of visualization. Maybe this can be better way to understand for someone
https://github.com/TropinAlexey/C-sharp-Access-Modifiers
All access modifiers' descriptions for C#

What does the "private" modifier do?

Considering "private" is the default access modifier for class Members, why is the keyword even needed?
There's a certain amount of misinformation here:
"The default access modifier is not private but internal"
Well, that depends on what you're talking about. For members of a type, it's private. For top-level types themselves, it's internal.
"Private is only the default for methods on a type"
No, it's the default for all members of a type - properties, events, fields, operators, constructors, methods, nested types and anything else I've forgotten.
"Actually, if the class or struct is not declared with an access modifier it defaults to internal"
Only for top-level types. For nested types, it's private.
Other than for restricting property access for one part but not the other, the default is basically always "as restrictive as can be."
Personally, I dither on the issue of whether to be explicit. The "pro" for using the default is that it highlights anywhere that you're making something more visible than the most restrictive level. The "pro" for explicitly specifying it is that it's more obvious to those who don't know the above rule, and it shows that you've thought about it a bit.
Eric Lippert goes with the explicit form, and I'm starting to lean that way too.
See http://csharpindepth.com/viewnote.aspx?noteid=54 for a little bit more on this.
It's for you (and future maintainers), not the compiler.
Explicitness. I never use the default and always explicitly add the modifier.
This could be because of my Java background where the default was 'package' (roughly equivalent to 'internal' in C#) and so the difference always bothered me. I found explicitness to be preferable.
I also use ReSharper now which defaults to being explicit, so it only confirms and reinforces my bias :)
The private modifier explains intent.
A private member variable is not intended for direct manipulation outside the class. get/set accessors may or may not be created for the variable.
A private method is not intended for use outside the class. This may be for internal functionality only. Or you could make a default constructor private to prevent the construction of the class without passing in values.
The private modifier (and others like it) can be a useful way of writing self documenting code.
As pointed out by Jon Skeet in his book C# In Depth, there is one place in C# where the private keyword is required to achieve an effect.
If my memory serves correctly, the private keyword is the only way to create a privately scoped property getter or setter, when its opposite has greater than private accessibility. Example:
public bool CanAccessTheMissileCodes
{
get { return canAccessTheMissileCodes; }
private set { canAccessTheMissileCodes = value; }
}
The private keyword is required to achieve this, because an additional property accessability modifier can only narrow the scope, not widen it. (Otherwise, one might have been able to create a private (by default) property and then add a public modifier.)
Private is only the default for methods on a type, but the private modifier is used elsewhere.
From C# Language Specification 3.0 (msdn) Section 3.5.1
Depending on the context in which a member declaration takes place, only certain types of declared accessibility are permitted. Furthermore, when a member declaration does not include any access modifiers, the context in which the declaration takes place determines the default declared accessibility.
Namespaces implicitly have public declared accessibility. No access modifiers are allowed on namespace declarations.
Types declared in compilation units or namespaces can have public or internal declared accessibility and default
to internal declared accessibility.
Class members can have any of the five kinds of declared accessibility and default to private declared accessibility. (Note that a type declared as a member of a class can have any of the five kinds of declared accessibility, whereas a type declared as a member of a namespace can have only public or internal declared accessibility.)
Struct members can have public, internal, or private declared accessibility and default to private declared accessibility because structs are implicitly sealed. Struct members introduced in a struct (that is, not inherited by that struct) cannot have protected or protected internal declared accessibility. (Note that a type declared as a member of a struct can have public, internal, or private declared accessibility, whereas a type declared as a member of a namespace can have only public or internal declared accessibility.)
Interface members implicitly have public declared accessibility. No access modifiers are allowed on interface member declarations.
Enumeration members implicitly have public declared accessibility. No access modifiers are allowed on enumeration member declarations.
For completenes. And some people actually prefer to be explicit in their code about the access modifiers on their methods.
For symmetry and to conform with coding styles that like everything to be explicit (personally I like it ...)
Using private explicitly signals your intention and leaves clues for others who will support your code ;)
Some coding styles recommend that you put all the "public" items first, followed by the "private" items. Without a "private" keyword, you couldn't do it that way around.
Update: I didn't notice the "c#" tag on this so my answer applies more to C++ than to C#.
I usually leave private out but I find it useful for lining up code:
private int x;
public string y;
protected float z;
VS:
int x;
public string y;
protected float z;
As Robert Paulson said in his answer, the private modifier is not just used on members, but also on types. This becomes important because the default for types is internal which can leak unintentionally if you use the InternalsVisibleToAttribute.
Actually, if the class or struct is not declared with an access modifier it defaults to internal.
So if you want to make it private, use private.

Categories

Resources