嵌套类构造函数的可见性
有没有办法限制C#中嵌套类的实例化?我想防止嵌套类从除嵌套类之外的任何其他类实例化,但允许从其他代码完全访问嵌套类。
Is there a way to limit the instantiation of the nested class in C#? I want to prevent nested class being instantiated from any other class except the nesting class, but to allow full access to the nested class from other code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
通常,我会为要向其他类公开的功能创建一个接口,然后将嵌套类设为私有并实现该接口。这样嵌套类定义可以保持隐藏:
Usually I create an interface for the functionality you want to expose to other classes, then make the nested class private and implement that interface. This way the nested class definition can stay hidden:
如果您需要满足以下要求之一:
我找到了类似于ak99372发布的解决方案 ,但不使用静态初始值设定项:
这个想法是
Nested
类的构造函数只能由Factory
类访问,该类嵌套更深一层。Factory
类显式实现私有接口IPrivateFactory
中的CreateInstance
方法,以便只有那些可以看到IPrivateFactory
的人可以调用CreateInstance
并获取Nested
的新实例。Outer
类外部的代码无法在不询问Outer.GetNested()
的情况下自由创建Nested
的实例,因为Outer.Nested< /code> 的构造函数是私有的,因此无法直接调用
Outer.Nested.Factory
可以实例化,但无法强制转换为IPrivateFactory
,因此无法调用其CreateInstance()
方法。请注意,我不建议在生产代码中大量使用该模式,但我发现这是一个在极少数情况下有用的技巧。
If you need to meet one of the following requirements:
I found a solution similar to the one posted by ak99372, but without using a static initializer:
The idea is that the
Nested
class's constructor is accessible only to theFactory
class, which is nested one level deeper. TheFactory
class explicitly implements the methodCreateInstance
from the private interfaceIPrivateFactory
, so that only those who can seeIPrivateFactory
can callCreateInstance
and get a new instance ofNested
.Code outside the
Outer
class can't freely create instances ofNested
without askingOuter.GetNested()
, becauseOuter.Nested
's constructor is privated, so they can't call it directlyOuter.Nested.Factory
can be instantiated, but can't be cast toIPrivateFactory
, so itsCreateInstance()
method can't be called.Note that I wouldn't recommend using that pattern heavily in production code, but it's a trick I find useful to have up my sleeve on rare occasions.
简而言之,不,你不能那样做。有一个可访问性修饰符“public”,意思是“可以被我内部或外部的任何东西访问”,还有一个可访问性修饰符“private”,意思是“可以被我内部的任何东西访问”。没有修饰符意味着“可以直接访问我之外的东西,但不能访问它之外的任何东西”,这就是您需要将构造函数标记为的修饰符。类型系统的设计者认为这根本不是一个有用的概念。
您能描述一下为什么您想要这种疯狂的可访问性吗?也许有更好的方法来获得你想要的东西。
In short, no, you cannot do that. There is an accessibity modifier "public" which means "accessible by anything inside me or outside me" and there is an accessibility modifier "private" which means "accessible by anything inside me". There is no modifier which means "accessible to the thing immediately outside me but not to anything outside it", which is what you would need to mark the constructor as. That's simply not a concept that the designers of the type system thought would be useful.
Can you describe why you want this crazy kind of accessibility? Perhaps there is a better way to get what you want.
由于 C# 语法中没有任何内容,因此您必须在它们之间实现类似“合同”的内容。您可以利用嵌套类可以访问其父级的私有字段的事实:
当然您可以调整契约来处理不同的参数
Since there is nothing in C# syntax you'll have to implement something like "a contract" between them. You can take advantage of the fact that nested class can access private fields of its parent:
Of course you can adjust the contract to handle different parameters
使用 C# 11 的新静态抽象接口成员,您可以非常巧妙地限制嵌套类的实例化:
With the new static abstract interface members of C# 11 you can limit the instantiation of nested classes quite neatly:
对于 Joshua Smith 提出的答案,我发现有必要强制 FriendClass 的静态构造函数运行,这是通过从 ParentClass 的静态构造函数调用 FriendClass 上的空静态 Initalize() 方法来实现的。
For the answer proposed by Joshua Smith I found it necessary to force the static constructor of FriendClass to run, achieved by calling an empty static Initalize() method on FriendClass from the static constructor of ParentClass.
请注意,您可以从 Nested 访问 Outer 的私有成员。
Note that you can access private members of Outer from Nested.