Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#中是否可以强制只能从构造函数调用私有函数?_C#_Constructor_Assert - Fatal编程技术网

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

在C#中是否可以强制只能从构造函数调用私有函数?,c#,constructor,assert,C#,Constructor,Assert,我发现在某些情况下,一个构造函数中有很多代码,或者一个类有两个或两个以上的构造函数,它们的代码相当。在这些情况下,我经常创建一个私有方法。在前一种情况下提高可读性,在后一种情况下防止代码重复 在某些情况下,这会导致只能从构造函数调用私有方法(无论出于何种原因)。有没有办法强制执行?我可以想象这样做: using System.Diagnostics; public class Foo { private bool _constructing = true; private Foo()

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

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

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
(构造函数):


要防止内联,可以将
MethodImplOptions.noinline
放在方法
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()
的使用只能在构造期间调用,虽然这不会强制您的公共构造函数调用
:this()
但您不能保证您的公共构造函数会调用
Initialize()

您可以链接构造函数,这样就不需要单独的方法。这假设在不同的构造函数中发生类似的事情。。。将
标记为
只读
。通过这种方式,您将确保没有其他代码能够将其还原为
true
。由于该方法是私有的,我不明白您为什么需要做任何事情,而只是在该方法旁边放一条注释,说明只能从构造函数调用它。请使用构造函数链接。如果您需要初始化一个
只读
字段,那么
初始化
方法是没有用的;忘了再次检查我自己的示例代码-抱歉!您仍然可以调用
B(“.ctor”),但至少这会引起警告。但在这种情况下,我不能仍然调用
B(“.ctor”)
?AFAIK
CallerMemberName
仅在未提供可选参数的情况下才被填充…我只是尝试使用CallerMemberName(这似乎是我正在寻找的),但不幸的是,目前我仍坚持使用.NET 4.0。。。这似乎已经在4.5中实现了,是吗?@MHJFaase:看看这个:我会接受这个作为解决方案——虽然我不能用这种方式,但它看起来确实是最接近我想要的——我要么开始使用4.5,要么只是咬紧牙关一段时间……哎呀——这实际上是我在我的示例中想要做的——但这并不完全是我想要的。编辑后,我将编辑示例:您需要在另一个构造函数(具有唯一参数的private)中打开
Initialize
方法,然后调用它。在您的例子中,似乎最好使用无参数私有构造函数。这里有一种情况特别相关:序列化。我经常希望在可序列化类中使用Initialise()函数,构造函数和反序列化器都可以调用该函数,这两个类都有初始化实例内容的任务。如果能够指定允许这个Initialise()函数修改只读字段,那就太好了。
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()
    {
    }
}