【发布时间】:2013-01-24 16:22:15
【问题描述】:
我已经阅读了一些关于 SO(和其他地方)关于这个主题的讨论,但无法收集到明确的答案。
我想确保给定的类 A 只能由特定的类 B 创建。在 C++ 中,我将 A 的构造函数设为私有,并将 B 指定为友元。现在只有 B 可以创建 A。
如果确实有的话,在 C# 中执行此操作的惯用方式是什么?
【问题讨论】:
标签: c# constructor factory
我已经阅读了一些关于 SO(和其他地方)关于这个主题的讨论,但无法收集到明确的答案。
我想确保给定的类 A 只能由特定的类 B 创建。在 C++ 中,我将 A 的构造函数设为私有,并将 B 指定为友元。现在只有 B 可以创建 A。
如果确实有的话,在 C# 中执行此操作的惯用方式是什么?
【问题讨论】:
标签: c# constructor factory
您可以为此使用 private 内部类。
但是,这用途有限。
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()
{
}
}
}
【讨论】:
public _A吗?
我假设外部代码需要引用A,但应该不能创建实例。
没有简单的方法可以实现这一点。如果您将A 的构造函数设为internal,那么只有与A 在同一程序集中的代码才能构造它(不使用反射)。
您可以创建一个StackTrace 的实例并检查索引1 处的帧,看看它是否来自B 的方法,但这可能会导致性能问题,而且很友好一个黑客。
【讨论】:
这是可行的,但以令人讨厌的方式。可以说比 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;
}
}
【讨论】: