default access modifier for enum in C# - c#

According to MSDN here and here (as well as the accepted answer to this qstn), the default accessibility for enums is public.
However, this code:
public class Test
{
enum Color { RED, BLUE, GREEN };
public void SetColor(Color c) { }
}
will raise this compile error:
Error 1 Inconsistent accessibility: parameter type 'Test.Color' is less accessible than method 'Test.SetColor(Test.Color)'
(which is the same error you get when you set the enum as private.) This error can only be resolved by explicitly modifying enum as public. Is the documentation incorrect?
[I'm compiling with C# 2010 and .NET 4.0.]

That is not true.
The default accessibility for enum types is the same as any other type; internal for top-level types and private for nested types.
The pages you linked to state that the default (and, in fact, only) accessibility level for enum members (Red, Blue, etc) is public.

The mentioned MSDN articles and SO answer refer to "enum member" - i.e. e.g Test.Color.RED, not Test.Color as the enum itself.
Test.Color is a member of class - thus private.

That table is referring to the members; the members are "RED", "BLUE" and "GREEEN", and are indeed public literal constants, and accessibility specifies are not permitted.
Contrast, say, to the members of a class (fields, methods, constants, etc); here, as per the table, the default is "private", although you can specify higher accessibility.

I believe that because you're declaring inside the class without a modifier, it assumes to be private as it's the standard behavior in a class. Specify public that should solve the issue. However, note that Code Analysis will recommend this enum be placed outside the class.

it is because you dont have public, protected, internal on your enum, it takes the default value (which is internal for classes and enums)
sorry for the confusion, you can't make the property public because the enum is private
the public property would be externally public should someone use your program and the compiler tells you about it

Related

make access modifier one for all members in class

Have defined such class:
class Data
{
internal string f_source;
internal string f_output;
internal string password;
}
As you see, I'm defining the access modifier for each member in it, explicitly.
Does exist some way to define the default access modifier for the all members in class at once?
Maybe, there is some attribute that makes such dream come true... Don't know...
I've tried to use the access modifier before the class declaration:
internal class Data
{
string f_source;
string f_output;
string password;
}
But, no success!
Are the any suggestions: "how to fix such a problem?"
By design what your are asking for is not possible in C#.
The specifications of C# specifies which access modifier to use if none is given. The default is the most restricted access modifier that's legal. That is a type directly in a namespace (Ie not a nested type) is internal whereas any member is private unless otherwise specified.
This is, I'm sure, a design decision partly based on experience with how access modfiers in C++ works. a series of bugs can come from have specific sections of a file declaring private, publicetc. It's a lot more expressive to have to state it (or know that if not specified it's as restricted as possible). Keeping the restricted as the default fits well with keeping as much as possible as internal (*) implementation details and only exposing what you really need to expose
(*) not the modifier
Your second definition type makes your class accessable only within same assembly just for that class. No way to make all class members as internal for all members.
Chek this: msdn internal defination&example
Good Luck!

Enum TryParse with base class qualifier

I have an enum (let's say DemoEnum) and I want to parse a value to this enum. I am writing
DemoEnum value;
if(DemoEnum.TryParse("input", out value))
{
this.Value = value;
}
Now the resharper suggests me, to use the base class qualifier.
I just want to know what's the benefit of using the base class qualifier?
Generally, it is a good idea to use the most generic solution possible.
DemoEnum.TryParse("input", out value)
Is the same call as (you're just making the static call from an inherited class rather than the base class):
Enum.TryParse<DemoEnum>("input", out value)
Using the base class qualifier (Enum) instead of your specific enum (DemoEnum) would insulate you from possible side effects of changing DemoEnum in the future. The reality is that you're really only going to run into issues if you change DemoEnum to a class without changing the name.
This is generally a larger issue when using classes (and ReSharper will give the same guidance in those situations).
The TryParse() method is a static method defined in the Enum class. Since your enum inherits everything from the Enum class, it also "inherits" static members. It's not true inheritance, the static members are just visible from the class.
The other answers are wrong in that some special translation is being done for you. All you are doing is accessing the static member from a derived class since all static members are accessible through your enum. The type of the identifier that you are accessing the static method from has no bearing at all on what the generic parameters are, only what the compiler is able to infer from them (or you explicitly provide).
To illustrate my point, consider these two enums:
enum First { A, B }
enum Second { A, B }
First firstVar;
Second secondVar;
// note we're using the `First` name
First.TryParse("A", out firstVar); // valid, firstVar <= First.A
First.TryParse("B", out secondVar); // still valid, secondVar <= Second.B
// is equivalent to
Enum.TryParse<First>("A", out firstVar); // generic type is inferred from type of firstVar
Enum.TryParse<Second>("B", out secondVar); // generic type is inferred from type of secondVar
What ReSharper is telling you is that you should be accessing the static member from the class that defined actually the member. Why should you do this?
Consider what would happen if your derived type defined a static member with the same exact name. (it's not possible in this case with enums but applicable to classes in general) What would happen to your code then? Any code that accessed the static member through the derived class will take on the new value and you will probably get no new warning about it. This may or may not be desired behavior so ReSharper is preemptively warning you that you should use the actual class that defined it (the base).
Looks like Resharper is suggesting you use Enum.TryParse - http://msdn.microsoft.com/en-us/library/dd783499.aspx
I bet if you look at the IL... DemoEnum.TryParse is just doing a base.TryParse
When you write DemoEnum.TryParse, the compiler transforms it to Enum.TryParse<DemoEnum>. There is no functional difference, and you don't really need to be insulated from possible side effects because you can't define methods in an enum type, so TryParse can't be redefined. My best guess is that it's a style preference.

Enum on namespace level - still needs to be public?

I am not sure why the enum there must be public in order to be used with the delegate. I assumed when on namespace level, the whole app can access it, as it is in the scope.
namespace Test
{
enum Days
{
Monday,Tuesday
}
class TestingClass
{
public delegate void DelTest(Days d) /// ERROR, type enum is less accessible
}
}
Your delegate type is actually declared within an internal class, so it's effectively internal too (in some senses, anyway). That's why your example as shown will compile (after adding the semi-colon). To make it break, you'd have to make TestingClass public too. So options:
Leave it as shown
Make the delegate explicitly internal, if you want TestingClass to be public
Make the enum explicitly public, if you want everything to be public
Just to explain why your current code would be broken if TestClass were public: the delegate would be public, and therefore visible outside the current assembly. That means all its parameters and the return type have to be visible too.
Don't forget that the default access level for a member in C# is always "the most restrictive access level that could be explicitly specified for that member" - so for a top-level type (including an enum), the default accessibility is internal.
The accessibility of your enum must match the delegate. Think about how you're going to call it.
new TestingClass.DelTest(Days.Monday).Invoke();
To be able to do this from a different assembly, the Days enum must be public. If you don't want it to be public, change the accessibility of the delegate to match that of the enum, e.g. set both to be internal.
I assumed when on namespace level, the whole app can access it
No, the whole assembly can access it. The default access level is internal.
Edit: When I change your code to use a public class:
enum Days { ... }
public class TestingClass { void M(Days d) {} }
I do get a compile error
Inconsistent accessibility: parameter type 'Test
.Days' is less accessible than ...
And that is what #firefox explains: a parameter-type in a public method must also be public, to avoid inconsistencies. Currently your Days type is less accessible (internal).
This piece of code compiles fine for me too, with the addition of the semi colon.
The error of "parameter type is less accessible than the delegate" would only occur if the class accessibility is raised, as currently they are defined with the same accessibility level, internal.
e.g.
namespace Test
{
enum Days
{
Monday, Tuesday
}
public class TestingClass
{
public delegate void DelTest(Days d); // This will produce an error...
}
}

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

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.

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