gpt4 book ai didi

c# - 如何在 C# 中模拟 "friend"?

转载 作者:太空狗 更新时间:2023-10-30 00:44:52 25 4
gpt4 key购买 nike

我需要在 C# 中实现一些 C++ 风格的“ friend ”功能,并且正在寻找想法。

考虑两个密切相关的类:Node 和 NodePart。节点包含 NodeParts,这些 NodeParts 是通过来自其他系统的公共(public) AddPart() 调用添加的,这些系统具有这些系统构造的部分。 Node 需要“进入”NodePart 以执行一些非常具体的通知,NodePart 将在一些处理后通过单独的虚拟保护方法分发给任何派生类。 (对于任何熟悉基于组件的游戏对象编程的人来说,这是一回事。)

我希望能够让 NodePart 为 Node 提供一种获取这几个通知方法的方法,而无需让系统中的任何其他类型执行此操作。 Node 没有必要访问任何其他 NodePart 内部,只需转发一些私有(private)通知即可。

现在,将这些类放在一个程序集中并使用“内部”显然可以解决问题,但我正在寻找比这更好的模式。 (我对为我将来要使用的每组类生成新程序集并不真正感兴趣。)

除了 reflection + invoke 这令人厌恶和脆弱之外,您还能想到什么其他模式来解决这里的这个问题?我敏锐的直觉告诉我接口(interface)是解决方案的一部分,但我想不出具体方法。

(注意:我对默默无闻的安全性没意见。这个系统不必 100% 证明不会被滥用——只要足以阻止人们做他们不应该做的事就够了。我们不是在制造除颤器在这里。)

更新:下面的许多答案都需要多个程序集。正如我上面提到的,我真的很想避免这种情况。我不想为每个组件放置一个系统。我们有足够多的东西了,由于我们使用 XAML,我不能沿着 IL 链接路线走下去。但无论如何还是感谢您的回答。 :)

更新 2: 我在 Linqpad 中四处乱逛,并根据以下答案提出了一些选择。您最喜欢/最不喜欢哪个,为什么?

选项 1:过时

#pragma warning disable 612 // doc this
public sealed class Node : NodePart.SystemAccess {
#pragma warning restore 612
NodePart _part;

public NodePart Part {
get { return _part; }
set { _part = value; NotifyAdded(_part); }
}
}

public class NodePart {
void NotifyAdded() { Console.WriteLine("Part added"); }

[Obsolete] public class SystemAccess // doc this
{
protected void NotifyAdded(NodePart part) { part.NotifyAdded(); }
}
}

还不错。有点奇怪,但奇怪的地方非常有限。我倾向于这个,因为它比下一个选项紧凑得多。

选项 2:访问 + 破解

public sealed class Node {
static readonly NodePart.ISystemAccess _systemAccess;

static Node() {
_systemAccess = (NodePart.ISystemAccess)typeof(NodePart)
.GetNestedTypes(BindingFlags.NonPublic)
.Single(t => t.Name == "SystemAccess")
.GetConstructor(Type.EmptyTypes)
.Invoke(null);
}

NodePart _part;

public NodePart Part {
get { return _part; }
set { _part = value; _systemAccess.NotifyAdded(_part); }
}
}

public class NodePart {
void NotifyAdded() { Console.WriteLine("Part added"); }

internal interface ISystemAccess {
void NotifyAdded(NodePart part);
}

class SystemAccess : ISystemAccess {
void ISystemAccess.NotifyAdded(NodePart part) {
part.NotifyAdded();
}
}
}

哈卡哈卡哈卡。我的原始版本没有 reflect+invoke 并且会依赖于 SystemAccess 是非显而易见的。这也可能没问题,但我有点喜欢我在这里获得的额外安全性,即使这可能没有必要。

最佳答案

使 NodePart 成为 Node 中的嵌套类,它将能够访问其所有私有(private)成员。

如果那不可能(不想要 using Node?),那么您可以尝试分部类。不过,我不知道它是如何工作的,因为我从来没有像那样以更高级的方式真正使用过它们。

关于c# - 如何在 C# 中模拟 "friend"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6824096/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com