ded*_*cos 2 c# struct default-constructor
有没有办法阻止调用结构的默认构造函数?
我的项目中有几个结构,其中一些我不能让任何情况下调用默认构造函数(这将导致我的代码中出现很多不需要的行为).
PS.:在编写某些特殊结构(无法用默认构造函数实例化)编译时,只是指示我的任何解决方案"错误地"实例化对我来说都没问题.一个简单的编译器警告应该足够我的情况!
你不能.
自然地,
struct必须将a的所有字段初始化为某个值.struct不能有无参数构造函数class如果您需要这样的行为或者检查您的设计,请使用a .
当您处理结构时,C# 希望确保您已初始化该结构的所有字段。
一种选择是提供一个构造函数,该构造函数将首先调用默认构造函数,然后再进行自定义初始化:
public S(int x) : this()
{
/* custom initialization logic */
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是提供一个构造函数,该构造函数可以在其自己的主体中可靠地初始化结构体的所有字段,在这种情况下,您不需要链接默认构造函数:
public S(int x)
{
this.X = x;
/* custom initialization logic */
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是跳过调用构造函数,而是在实际使用结构之前手动初始化该结构:
S s;
s.X = 5;
Run Code Online (Sandbox Code Playgroud)
在上述选项中,只有第一个对默认构造函数执行逻辑调用,而其他两个则跳过该调用。
坏消息是,出于安全原因,CLR 在幕后始终会为您提供零初始化内存,这几乎与调用 C# 默认构造函数完全相同。你可以这样观察:
S s;
S* ptr = &s;
int x = (*ptr).X;
Console.WriteLine(x); // will print 0
Run Code Online (Sandbox Code Playgroud)
好消息是,在大多数情况下,这并不重要。C# 默认构造函数并不是 CLR 意义上的真正构造函数。new T()any 的表达式T : struct相当于default(T),这只是表达获取类型 struct 的零初始化实例的一种方式T。这也是为什么您不能将其设为私有或向其添加自定义逻辑的原因。
因此,C# 默认结构构造函数不能具有任何逻辑外部可观察到的副作用。这给我们带来了一个问题:您想避免哪些类型的影响?
请记住,如果您的问题是您的结构对于全零位模式无效,并且您担心某些客户端代码可能会尝试像这样使用它,那么有一个解决方法:
struct S
{
private bool _isValid;
/* rest of your struct */
}
Run Code Online (Sandbox Code Playgroud)
任何零初始化的结构都不会设置其有效性标志,一旦对结构执行任何操作(您可以控制),您就可以使用它来抛出异常。
毕竟,如果出于某种原因您仍然需要一个以某种方式跳过调用任何构造函数(无论是真实的还是明显的)的结构实例,您将必须自己为该结构分配一些内存:
S* ptr = (S*) Marshal.AllocHGlobal(Marshal.SizeOf<S>());
Run Code Online (Sandbox Code Playgroud)
(*ptr).X您现在可以使用or形式的表达式ptr->X直接读取和写入该结构。