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

时间:2015-01-14 10:07:53

标签: c# constructor assert

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

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

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
  }
}

3 个答案:

答案 0 :(得分:9)

构造函数可以互相调用:

class Foo
{
    private Foo()
    {

    }

    public Foo(int value) : this()
    {

    }
}

我想,您可以使用此功能。

答案 1 :(得分:4)

您可以使用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上。

答案 2 :(得分:3)

我建议你这样做:

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()的使用只能在构造期间调用,虽然这不会强制您的公共构造函数调用: this(),但您没有任何此类保证,您的公共构造函数将调用{{1}无论如何。