在 C# 中是否可以强制只能从构造函数调用私有函数?

Is it possible in C# to force a private function to be callable from the constructor only?

我发现在某些情况下,构造函数中有很多代码,或者 class 有两个或多个具有可比代码的构造函数。在这些情况下,我通常会创建一个私有方法。前者是为了提高可读性,后者是为了防止重复代码。

在某些情况下,这会导致只能从构造函数调用的私有方法(无论出于何种原因)。有没有办法强制执行此操作?我可以想象做这样的事情:

using System.Diagnostics;

public class Foo
{
  private bool _constructing = true;

  private Foo()
  {
    _constructing = false;
  }

  public Foo(string someString) : this()
  {
    // constructor-specific code
    Initialize();
  }

  public Foo(double someDouble) : this()
  {
    // constructor-specific code
    Initialize();
  }

  private void Initialize()
  {
    Debug.Assert(!_constructing, "Initialize method should only be called from constructor");

    // shared code
  }
}

但这感觉有些笨拙。谁有更好的建议?

编辑:为示例添加了构造函数链接;我的意思是在原始示例中。

编辑:我想我在原来的问题中遗漏了一点——虽然链接构造函数在某些情况下确实提供了解决方案,但链接的代码总是在您链接的构造函数中的代码之前执行( ,顺便说一句,这就是为什么上面的例子不起作用)。在某些情况下,您想要执行共享代码的某些部分,然后再做其他事情。我将添加另一个示例来反映这一点:

using System.Diagnostics;

public class Foo
{
  private bool _constructing = true;

  public Foo(string someString)
  {
    // constructor-specific pre-processing code
    Initialize();
    // constructor-specific post-processing code

    _constructing = false;
  }

  public Foo(double someDouble)
  {
    // constructor-specific pre-processing code
    Initialize();
    // constructor-specific post-processing code

    _constructing = false;
  }

  private void Initialize()
  {
    Debug.Assert(!_constructing, "Initialize method should only be called from constructor");

    // shared code
  }
}

您可以为此使用 CallerMemberName。编译器将用调用该方法的原始方法填充它。在这种情况下 .ctor (构造函数):

public static class Program
{
    static void Main(string[] args)
    {
        A a = new A();
    }
}

class A
{
    public A()
    {
        B();
    }

    [MethodImplOptions.NoInlining]
    private void B([CallerMemberName] string caller = null)
    {
        if (caller == ".ctor")
        {
        }
    }
}

要防止内联,您可以将 MethodImplOptions.NoInlining 放在方法 B 上。

构造函数可以相互调用:

class Foo
{
    private Foo()
    {

    }

    public Foo(int value) : this()
    {

    }
}

我想,你可以使用这个功能。

我建议你这样做:

public class Foo
{
    private Foo()
    {
        // private constructors can only be called from
        // within the class during constuction
    }

    public Foo(string someString) : this()
    {
    }

    public Foo(double someDouble) : this()
    {
    }
}

: this() 的使用只能在构造期间调用,虽然这不会强制您的 public 构造函数调用 : this(),但您没有任何此类保证 public 构造函数无论如何都会调用 Initialize()