Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practices for restricting access to enum parameter in C# [closed]

Consider for the question this String.Split overload, which takes a StringSplitOptions enum as a parameter.

Isn't it bad that the enum itself is public and accessible to everything that includes the System namespace? I mean, the enum is completely specific to options of the Split method, yet it's available outside of it's scope.

Perhaps there is a better way to model this, like putting the enum inside the String class itself, and accessing it by using String.SplitOptions for instance? I very rarely see this (I actually can't remember any such case now), so I assume it is not preferred for some reason. In general, I think reducing the scope of things is a best practice because you lower the chance of problems occurring by using a class/member in an incorrect scope, so to speak.

I'm using Split as an example here, but it is quite common for a Enum to be used only by a method or class in our code base too. I generally create the enum as a public type in a separate cs file like any other class, but I would love to hear other approaches to this 'problem'.

Update:

I just found this article that attacks this exact problem, with a Folder class and a Filter enum but again seems go against what I believe would be more correct in that case (placing the enum inside the class somehow). One of the comments in there from ToddM (which I happen to agree with) states:

...

But, even then, I feel your logic is wrong. Your main complaint against embedding the enum inside of the class is that it will take too long to type. Given how verbose C# tends to be, this is not really a sensible argument. In VS, CTRL+SPACE is your friend.

Logically, I feel placing the enum inside of the class is far more correct. Take your example: what is a MyNameSpace.Filter? Where does it apply? I guess it's a filter for your namespace? It's impossible to tell, especially if your namespace grows to contain dozens of classes.

Now consider MyNameSpace.Folder.Filter -- it is, in my mind, far more intuitive that Filter applies in some way, shape, or form to the Folder class. Indeed, another class can be added to the namespace with its own concept of filter, one of whose members may be 'File'. Just because you've introduced a new class into the namespace doesn't give you the right to pollute that namespace with various 'helper' types. If you are developing as part of a large development team, your style is, well, rude.

...

like image 249
julealgon Avatar asked Oct 18 '13 13:10

julealgon


1 Answers

It's an interesting idea to nest the enum in order to suggest that it has a reduced scope, or to give it better semantics. I have used this idea before in order to have both error codes and warning codes in a post-compiler I developed. This way, I could use the same enum name Code nested either in the Error class or the Warning class.

On the other hand, public nested types are generally discouraged. They can be confusing to clients who have to qualify them with the outer class name. Look at the related guidelines on MSDN. Some that are relevant:

DO NOT use public nested types as a logical grouping construct; use namespaces for this.

AVOID publicly exposed nested types. The only exception to this is if variables of the nested type need to be declared only in rare scenarios such as subclassing or other advanced customization scenarios.

DO NOT use nested types if the type is likely to be referenced outside of the containing type.

For example, an enum passed to a method defined on a class should not be defined as a nested type in the class.

I believe those guidelines were followed when developing the StringSplitOptions enum, and most of the others in the BCL.

like image 87
Jordão Avatar answered Sep 17 '22 18:09

Jordão