具有自动实现的属性和构造函数初始值设定项的结构

本文关键字:结构 实现 属性 构造函数 | 更新日期: 2023-09-27 18:34:14

>最近编译器警告和(非常有用的(提示我编写下面的代码。

我不知道你可以这样做,但它是完全合法的,而且很方便,因为我可以声明一个具有类似于非托管结构的公共字段的公共属性的托管结构,并且还可以使用对象初始化它,而不必将所有字段作为参数传递。

让我感到困惑的是,这似乎调用了显式无参数构造函数,这对于这个结构来说当然是非法的。

这是怎么回事,是否一直支持此语法?

internal struct IconEntry
{
    public byte Width { get; set; }
    public byte Height { get; set; }
    public byte ColorCount { get; set; }
    public byte Reserved { get; set; }
    public short Planes { get; set; }
    public short BitCount { get; set; }
    public int BytesInRes { get; set; }
    public int ImageOffset { get; set; }
    public IconEntry(BinaryReader reader)
        : this()
    {
        Width = reader.ReadByte();
        Height = reader.ReadByte();
        ColorCount = reader.ReadByte();
        Reserved = reader.ReadByte();
        Planes = reader.ReadInt16();
        BitCount = reader.ReadInt16();
        BytesInRes = reader.ReadInt32();
        ImageOffset = reader.ReadInt32();
    }
}

具有自动实现的属性和构造函数初始值设定项的结构

结构总是有一个不能被覆盖的公共无参数构造函数:http://msdn.microsoft.com/en-us/library/aa288208%28v=vs.71%29.aspx

这意味着用户仍然可以创建此结构的实例,该实例不是根据您的逻辑初始化的,而是使用所有属性的默认值:

var s = new IconEntry();

所有结构都有一个无参数构造函数 - 它只是隐式的(例如,它始终存在于默认例程中 - 将所有值设置为 0( - 您只是不能有一个显式的(例如,您在代码中定义自己的构造函数(。

有什么理由为结构公开属性而不是字段吗? 如果数据类型的语义暗示

    实例
  1. 的整个状态将完全由某些公共成员公开的值定义,因此,所有这些实例报告或包含相同值的两个实例将被视为相同。
  2. 给定所讨论的所需值,可以轻松创建具有上述成员的任意值组合的结构实例。

这听起来非常适合 PODS(普通旧数据结构(。 公开字段比结构属性更高效,更不古怪。 鉴于所有结构类型始终公开所有字段以进行结构赋值的更改或捕获,因此结构属性提供的封装价值极其有限。

按照您编写构造函数的方式,您的结构将所有字段设置为 all-bits-zero,然后重复传递给方法,这些方法将使用所需的值一次更新一个字段。 结构被指定为由this初始化为全位零这一事实将使编译器满意,但使用许多单独的属性来逐个设置字段是低效的。

顺便说一下,在许多情况下,比构造函数更好的是静态方法,它只是将结构作为ref参数。 在许多情况下,将构造函数与结构一起使用将导致不必要的复制操作,这可以通过使用带有 ref 参数的静态方法来避免。

由于结构是值类型,因此,如果要显式调用构造函数,则应初始化它的数据成员。并提及"this(("到亲密的编译器以完成自动实现属性的分配(如果您提到任何内容(。

struct Student
{        
    string _sname;       
    public int ID
    {
        get; set;
    }
    internal Student(string sname):this()
    {            
        _sname = sname;
    }
    internal void PrintDetails()
    {
        Console.WriteLine("ID : {0} Name: {1}", ID, _sname);
    }
}

主要方法:

class Program
     {
         static void Main()
         {
             Student st = new Student("John")
             {
                 ID=101
             };
             st.PrintDetails(); 
         } 
     }
Output:
ID : 101 Name: John

如果您没有提到"this((",编译器会强制要求您完成 ID 属性的完整赋值。

如果未显式调用构造函数,编译器将隐式设置结构数据成员的默认值。