C# 中的封装和友谊
我当前的项目中有一个特殊案例。
我有:
public class A
{
// etc.
}
public class B
{
// etc.
private void HandleSomeEvent(object parameter)
{
// Etc.
}
protected void HandleSomeOtherEvent(object parameter)
{
// Etc.
}
}
我希望:
A
能够调用私有方法B.HandleSomeEvent
,但没有其他类(除了B
)能够做到A
能够调用受保护的方法B.HandleSomeOtherEvent
,但不能调用其他类(除了B
和B
的派生类)能够做到这
在 C# 中可能吗?
- 如果可以的话,该怎么做呢?
- 如果不可能,有哪些替代方案可以尽可能地保护
B
免受同一程序集中的类C
的篡改?
I have a particular case in my current project.
I have:
public class A
{
// etc.
}
public class B
{
// etc.
private void HandleSomeEvent(object parameter)
{
// Etc.
}
protected void HandleSomeOtherEvent(object parameter)
{
// Etc.
}
}
I want:
A
to be able to call the private methodB.HandleSomeEvent
, but no other class (butB
) to be able to do thatA
to be able to call the protected methodB.HandleSomeOtherEvent
, but no other class (butB
andB
's derived classes) to be able to do that
Is that possible in C# ?
- If possible, how to do that?
- If not possible, what are the alternatives which can protect
B
as much as possible from tampering from, say, a classC
in the same assembly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不,除非您使用反射:私有和受保护的成员无法从其他类访问。
您可以将 B 作为 A 内的嵌套类并将其设置为私有。然后您可以安全地增加 B 的两个方法的可见性,因为只有 A 才能调用它们(除非使用反射)。
No, unless you use reflection: private and protected members are not accessible from other classes.
You could make B a nested class inside A and make it private. Then you can safely increase the visibility of the two methods of B as only A will be able to call them (unless reflection is used).
这是可能的,但我通常只选择内部并假设程序集中的其他类表现良好。
例如,您可以将这些方法的委托传递给类 A,类 A 将它们存储在受保护的静态字段/属性中。
It is possible, but I'd usually just go with
internal
and assume that other classes in the assembly are well behaved.You could for example pass delegates to these methods to class A which stores them in
protected static
fields/properties.“2. 如果不可能,有哪些替代方案可以尽可能保护 B 免受同一程序集中的 C 类篡改?”
检查调用者的类型信息并抛出异常会起作用吗?
"2. If not possible, what are the alternatives which can protect B as much as possible from tampering from, say, a class C in the same assembly?"
Would checking the type info of the caller and throwing an exception work?
可以通过发出 A 的接口然后将其与具体实现分离。一旦你这样做了,你就可以写这样的东西
尽管
HandleSomeEvent()
是公共的,但只有A可以访问它,因为没有其他人可以获得A类的具体实例。它有一个私有构造函数,而工厂New()
方法返回一个接口。请参阅我的文章好友和内部界面成员,网址为接口编码无需任何成本了解详细信息。
It is possible by emitting an interface of A then separating it from a concrete implementation. Once you did it you can write something like this
In spite of the fact that
HandleSomeEvent()
is public only A can access it, since no one else can possibly get a concrete instance of A class. It has a private constructor, while the factoryNew()
method returns an interface.See my article Friends and internal interface members at no cost with coding to interfaces for details.
您可以将这两个方法标记为
internal
:这使得这两个方法对同一程序集中的所有类都可见(并且第二个方法对从
B
派生的所有类都可见)。没有办法使方法对特定的其他类可见。毕竟,您是控制程序集中所有类的人,因此您需要确保除
A
之外没有其他类调用这些方法。如果您确实需要工具的帮助,您可以编写 FxCop 规则或创建某种后构建操作来检查来自
A
之外的其他类的方法调用。You can mark both methods as
internal
:This makes the two methods visible to all classes in the same assembly (and also the second method visible to all classes derived from
B
).There is no way to make a method visible to a specific other class. After all, you're the one who's controlling all classes in your assembly, so it's up to you to make sure that no other class than
A
calls the methods.If you really need help from a tool with this, you could write an FxCop rule or create some kind of post-built action that checks for method calls from other classes than
A
.由于您的类
A
应该能够调用B
上的protected
方法,我认为它与它有某种关系。问问自己是否存在“is-a”关系,如“A is a B”。在这种情况下,您可以使A
继承自B
:现在,您可以在
B
上调用受保护的方法。但请不要只是继承,总是问自己继承是否有意义。As your class
A
should be able to callprotected
methods onB
, I figure it has some sort of relationship with it. Ask yourself if there is a "is-a" relationship, as in "A is a B". In this case, you can makeA
inherit fromB
:Now, you are able to call protected methods on
B
. But please, don't just inherit, always ask yourself if the inheritance makes sense.