在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”)
?AFAIKCallerMemberName
仅在未提供可选参数的情况下才被填充…我只是尝试使用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()
{
}
}