1

我已经阅读了一些关于 SO(和其他地方)关于这个主题的讨论,但无法收集到明确的答案。

我想确保给定的类 A 只能由特定的类 B 创建。在 C++ 中,我将 A 的构造函数设为私有,并将 B 指定为友元。现在只有 B 可以创建 A。

如果确实有的话,在 C# 中这样做的惯用方式是什么?

4

4 回答 4

6

您可以为此使用私有内部类。

但是,这用途有限。

class B
{
  private class A
  {
  }
}
于 2013-01-24T16:23:27.733 回答
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()
        {
        }

    }

}
于 2013-01-24T16:28:08.000 回答
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;
  }
}
于 2013-01-24T16:36:09.393 回答
1

我假设外部代码需要引用A,但不应该能够创建实例。

没有简单的方法可以实现这一点。如果你 makeA的构造函数internal,那么只有在同一个程序集中的代码A才能构造它(不使用反射)。

可以创建一个实例StackTrace并检查索引 1 处的框架,看看它是否来自 的方法B,但这可能会导致性能问题,并且是一种 hack。

于 2013-01-24T16:24:10.183 回答