我已经在SO(和其他地方)上阅读了关于这个主题的一些讨论,但没有能够收集到明确的答案。
我想确保给定的A类只能由特定的类B创建。在C ++中,我将A的构造函数设为private,并将B指定为朋友。现在只有B可以创建A.
在C#中这样做的惯用方法是什么,如果确实有一个呢?
答案 0 :(得分:6)
您可以使用私有内部类。
但是,这种用途有限。
class B
{
private class A
{
}
}
答案 1 :(得分:3)
你不能在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()
{
}
}
}
答案 2 :(得分:1)
我假设外部代码需要引用A
,但不应该能够创建实例。
没有简单的方法可以实现这一目标。如果你创建A
的构造函数internal
,那么只有与A
相同的程序集中的代码才能构造它(不使用反射)。
您可以创建StackTrace
的实例并检查索引1处的框架以查看它是否来自B
的方法,但这可能会导致性能问题,并且是一种黑客攻击。
答案 3 :(得分:1)
这是可行的,但是以一种讨厌的方式。可能在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;
}
}