我已经阅读了一些关于 SO(和其他地方)关于这个主题的讨论,但无法收集到明确的答案。
我想确保给定的类 A 只能由特定的类 B 创建。在 C++ 中,我将 A 的构造函数设为私有,并将 B 指定为友元。现在只有 B 可以创建 A。
如果确实有的话,在 C# 中这样做的惯用方式是什么?
我已经阅读了一些关于 SO(和其他地方)关于这个主题的讨论,但无法收集到明确的答案。
我想确保给定的类 A 只能由特定的类 B 创建。在 C++ 中,我将 A 的构造函数设为私有,并将 B 指定为友元。现在只有 B 可以创建 A。
如果确实有的话,在 C# 中这样做的惯用方式是什么?
您可以为此使用私有内部类。
但是,这用途有限。
class B
{
private class A
{
}
}
您不能在 C# 中使用 C++ 风格的方法。
我之前也遇到过这种情况,一般都是通过制作类A abstract
(需要继承)和构造函数protected
(只有继承自类的类才能调用构造函数)来解决。
然后我在 B 类中创建一个private
类(称为“_A”之类的东西)并从 A 继承。(_A 中没有其他代码。)_A 定义了一个公共的构造函数——因此对 B 可见(并且仅对 B 可见,因为 _A 是私人的)。
在 B 中,您可以创建 _A 的实例并将它们作为 A 返回(通过polymorphism)。
对于公共接口,我更喜欢这种方法,因为如果在其中实现 A 类,我的 B 类代码文件最终会很大。这只是我的偏好——其他人可能有不同的看法。
abstract class A
{
protected A()
{
}
/* implementation details... */
}
public class B
{
public A GetInstance()
{
return new _A();
}
private class _A : A
{
public _A()
{
}
}
}
这是可行的,但以令人讨厌的方式。可以说比 C++ 中的“朋友”概念更讨厌。
您可以声明私有构造函数和静态工厂方法,您将只允许特定类型调用此方法(通过检查 StackFrame)。
public class Foo
{
private Foo() { }
public static Foo Create()
{
if(GetCallingType() != typeof(Bar))
{
throw new Exception("Only Bar can create Foo");
}
return new Foo();
}
private static Type GetCallingType()
{
return new StackFrame(2, false).GetMethod().DeclaringType;
}
}
我假设外部代码需要引用A
,但不应该能够创建实例。
没有简单的方法可以实现这一点。如果你 makeA
的构造函数internal
,那么只有在同一个程序集中的代码A
才能构造它(不使用反射)。
您可以创建一个实例StackTrace
并检查索引 1 处的框架,看看它是否来自 的方法B
,但这可能会导致性能问题,并且是一种 hack。