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

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

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

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

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

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


当前回答

如果你正在使用c++,你发现你自己使用friend关键字,这是一个非常强烈的迹象,你有一个设计问题,因为为什么一个类需要访问其他类的私有成员?

其他回答

从。net 3开始就有了InternalsVisibleToAttribute,但我怀疑他们只是在单元测试兴起后才添加它来迎合测试程序集。我想不出还有什么其他理由来使用它。

它在组装层工作但它能完成内部不能完成的工作;也就是说,您希望分发一个程序集,但希望另一个非分布式程序集具有对该程序集的特权访问。

很正确地,他们要求好友程序集是强键的,以避免有人在你受保护的程序集旁边创建一个假装的好友。

我怀疑这与c#编译模型有关——在运行时构建IL和JIT编译。也就是说:c#泛型与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)

这种友谊可以通过分离接口和实现来模拟。其思想是:“需要一个具体实例,但限制该实例的构造访问”。

例如

interface IFriend { }

class Friend : IFriend
{
    public static IFriend New() { return new Friend(); }
    private Friend() { }

    private void CallTheBody() 
    {  
        var body = new Body();
        body.ItsMeYourFriend(this);
    }
}

class Body
{ 
    public void ItsMeYourFriend(Friend onlyAccess) { }
}

尽管ItsMeYourFriend()是公共的,但只有Friend类可以访问它,因为其他人不可能获得Friend类的具体实例。它有一个私有构造函数,而工厂New()方法返回一个接口。

有关详细信息,请参阅我的文章《朋友和内部接口成员,免费为接口编码》。

你可以用c#关键字“internal”来接近c++的“朋友”。