C#结构的注意事项 :

1. 结构是值类型,这意味这结构是存储在栈中的,结构存储的是变量的内容,而不是变量存储的地址(这是相当于引用类型的变量而言的)。将一个结构的实例赋值到另外一个结构实例时,会创建一个相同的内存副本,而不是创建一份结构的地址。这一点可以说是结构的本质了。

2. 结构中不能显式包含默认的无参的构造函数。注意是显式包含,如下的代码是错误的

代码
 struct MyStruct
    {
        
public MyStruct()
        {
            _field1 
= 0;
            _field2 
= 0;
        }

        
private int _field1;
        
public int Field1
        {
            
get { return _field1; }
            
set { this._field1 = value; }
        }

        
private int _field2;
        
public int Field2
        {
            
get { return _field2; }
            
set { this._field2 = value; }
        }
    }

再看如下代码:

代码
 struct MyStruct
    {
        
private int _field1;
        
public int Field1
        {
            
get { return _field1; }
            
set { this._field1 = value; }
        }

        
private int _field2;
        
public int Field2
        {
            
get { return _field2; }
            
set { this._field2 = value; }
        }
    }

 
class Program
    {
        
public static void Main()
        {
            MyStruct myStruct 
= new MyStruct();
            Console.WriteLine(myStruct.Field1 
+ " " + myStruct.Field2);

            Console.ReadKey();
        }
    }

 

以上代码是正确的,我们注意在Main方法中我们调用了结构体的默认无参构造函数,这不是与我们上面说的矛盾了吗?答案是不矛盾,因为就像我强调的不能显式包含无参构造函数,但C#却隐式包含了一个无参构造函数,该函数对结构体中所有的字段进行初始化,初始值为default指定的值。

3.不能对字段进行赋值,以下的代码是错误的:

struct MyStruct
    {

     //错误:不能对字段赋初值

      private int _field1 = 0; 
       ...

    }

 

 结构体所有字段初始化都必须在构造函数中进行,换句话说,如果你要定义带参数的构造函数,那你必须对所有的字段赋值,注意是字段。对于不想赋值的字段用default进行赋值,如下所示:

代码
  struct MyStruct
    {
        
public MyStruct(int field1, int field2)
        {
            _field1 
= field1;
            _field2 
= field2;
        }
     //注意这里
        
public MyStruct(int field1) : this(field1, default(int))
        {
            _field1 
= field1;
        }
    }

 

4.最后要注意的一点是:结构体是没有终结器的。因为如果是局部变量,结构体是存储在栈上的。如果作为引用类型的一部分,此时存储在堆上,他的内存会随着引用类型的垃圾回收被清理。