c++的friend关键字允许类a将类B指定为它的friend。这允许类B访问类A的私有/受保护成员。

我从来没有读过任何关于为什么c#(和VB.NET)中不包含这个的东西。大多数关于StackOverflow问题的答案似乎都在说它是c++的一个有用的部分,并且有很好的理由使用它。以我的经验,我不得不同意。

对我来说,另一个问题似乎是在问如何在c#应用程序中做类似于friend的事情。虽然答案通常围绕嵌套类,但它似乎没有使用friend关键字那么优雅。

最初的《设计模式》一书在其示例中经常使用它。

总之,为什么在c#中没有friend,在c#中模拟friend的“最佳实践”方法是什么?

(顺便说一下,internal关键字不是一回事,它允许整个程序集中的所有类访问内部成员,而friend允许你给某个类完全访问另一个类)


当前回答

这实际上不是c#的问题。这是IL中的一个基本限制。c#也受此限制,就像任何其他寻求可验证的。net语言一样。这个限制也包括c++ /CLI中定义的托管类(Spec第20.5节)。

话虽如此,我认为纳尔逊对为什么这是一件坏事有一个很好的解释。

其他回答

通过使用c#中的接口,您应该能够完成在c++中使用“friend”的相同种类的事情。它要求您显式地定义在两个类之间传递的成员,这是额外的工作,但也可能使代码更容易理解。

如果有人有一个合理使用“朋友”的例子,不能用界面模拟,请分享!我想更好地理解c++和c#之间的区别。

c#缺少“friend”关键字的原因与缺少确定性销毁的原因相同。改变传统让人们觉得自己很聪明,好像他们的新方式比别人的旧方式更优越。这都是关于骄傲。

说“朋友类不好”就像“不要用gotos”或“Linux比Windows好”一样是短视的。

“friend”关键字与代理类相结合是只向特定的其他类公开类的某些部分的好方法。代理类可以作为对所有其他类的可信屏障。“public”不允许任何这样的目标,如果真的没有概念上的“is a”关系,使用“protected”来获得继承的效果是很尴尬的。

关于信息,. net中另一个相关但不完全相同的东西是[InternalsVisibleTo],它允许一个程序集指定另一个程序集(例如单元测试程序集),该程序集(有效地)具有对原始程序集中的类型/成员的“内部”访问。

顺便说一句。 使用friend并不是违反封装,相反,它是加强封装。就像访问器+突变器、操作符重载、公共继承、向下强制转换等一样,它经常被误用,但这并不意味着关键字没有,或者更糟,没有一个坏的目的。

请参阅Konrad Rudolph在另一个线程中的消息,或者如果您愿意,请参阅c++常见问题解答中的相关条目。

不要再为这种限制找借口了。朋友是坏的,但内在是好的?它们是一样的东西,只是那个朋友让你更精确地控制谁可以访问谁不能访问。

这是强制封装范式吗?所以你必须写访问器方法,然后呢?你应该如何阻止所有人(除了类B的方法)调用这些方法?你不能,因为你也控制不了,因为你失去了“朋友”。

No programming language is perfect. C# is one of the best languages I've seen, but making silly excuses for missing features doesn't help anyone. In C++, I miss the easy event/delegate system, reflection (+automatic de/serialization) and foreach, but in C# I miss operator overloading (yeah, keep telling me that you didn't need it), default parameters, a const that cannot be circumvented, multiple inheritance (yeah, keep telling me that you didn't need it and interfaces were a sufficient replacement) and the ability to decide to delete an instance from memory (no, this is not horribly bad unless you are a tinkerer)