限制在C#中访问枚举参数的最佳做法

jul*_*gon 11 .net c# enums coding-style

考虑这个String.Split重载的问题,它以StringSplitOptions枚举作为参数.

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.

现在考虑MyNameSpace.Folder.Filter - 在我看来,它更直观,Filter以某种方式,形状或形式应用于Folder类.实际上,可以使用自己的过滤器概念将另一个类添加到命名空间,其中一个成员可能是"文件".仅仅因为你在命名空间中引入了一个新类,就没有权利用各种"帮助"类型来污染那个命名空间.如果您是作为大型开发团队的一员开发的,那么您的风格是粗鲁的.

...

Jor*_*dão 7

嵌套它是一个有趣的想法,enum以表明它具有缩小的范围,或者给它更好的语义.我之前使用过这个想法是为了在我开发的后编译器中同时包含错误代码和警告代码.这样,我可以使用Code嵌套在ErrorWarning类中的相同枚举名称.

另一方面,通常不鼓励使用公共嵌套类型.对于必须使用外部类名限定它们的客户来说,它们会让人感到困惑.请查看MSDN上的相关指南.一些相关的:

不要将公共嵌套类型用作逻辑分组构造; 为此使用名称空间.

避免公开暴露嵌套类型.唯一的例外是,嵌套类型的变量只需要在极少数情况下声明,例如子类化或其他高级自定义方案.

如果类型可能在包含类型之外引用,请不要使用嵌套类型.

例如,传递给类上定义的方法的枚举不应该被定义为类中的嵌套类型.

我相信在开发StringSplitOptionsenum 时会遵循这些指导原则,而BCL中的大多数其他指南也是如此.


Dav*_*rno 0

String.Split()是公开的,所以StringSplitOptions也必须是公开的。和StringStringSplitOptions存在于System命名空间中。两者都有公共范围。两者都不是“在[对方]范围之外可用”。