C#之结构

结构是用户定义的数据类型,与类非常相似,它们有数据成员和函数成员,但与类最重要的区别是:类是引用类型,而结构是值类似,结构是隐式密封的,这意味这它们不能被派生,所以结构类型不能为null,两个结构变量不能引用同一个对象, 在结构中,字段初始化语句是不被允许的.

struct StructureName{
    MemberDeclarations
}
namespace LearningCSharp 
{
    struct Point
    {
        public int x;
        public int y;
    }
    class Program
    {
        static void Main()
        {
            Point first, second, third;

            first.x = 10;first.y = 10;
            second.x = 20;second.y = 20;
            third.x = first.x + second.x;
            third.y = first.y + second.y;

            Console.WriteLine($"first:{first.x},{first.y}");
            Console.WriteLine($"second:{second.x},{second.y}");
            Console.WriteLine($"third:{third.x},{third.y}");

        }
    }
}

image-20210822172005132

对结构赋值

把一个结构赋值给另一个结构,就将一个结构的值复制给了另一个结构.这和复制类变量不同,复制类变量时,只复制引用.

namespace LearningCSharp 
{
    class CSimple 
    {
        public int x;
        public int y;
    }
    struct Simple
    {
        public int x;public int y;
    }
    class Program
    {
        static void Main()
        {
            CSimple cs1 = new CSimple(), cs2 = null;// 类实例
            Simple ss1 = new Simple(), ss2 = new Simple(); //结构实例

            cs1.x = ss1.x = 5;
            cs1.y = ss1.y = 10;

            cs2 = cs1;
            ss2 = ss1;

            cs2.x = 100;
            ss2.x = 200;

            Console.WriteLine($"cs1.x is {cs1.x}");
            Console.WriteLine($"cs2.x is {cs2.x}");
            Console.WriteLine($"ss1.x is {ss1.x}");
            Console.WriteLine($"ss2.x is {ss2.x}");

        }
    }
}

image-20210822210236370

构造函数

结构可以有实例构造和静态构造函数,但不能有析构函数.

实例构造函数

语言隐式地为每个结构提供一个无参数的构造函数.这个构造函数把结构的每个成员设置为该类型的默认值.值成员设置成它们的默认值,值成员设置为它们的默认值,引用成员设置为null.

namespace LearningCSharp 
{
    class CSimple 
    {
        public int x;
        public int y;
    }
    struct Simple
    {
        public int x;public int y;
        public CSimple z;
    }
    class Program
    {
        static void Main()
        {
            CSimple cs1 = new CSimple(), cs2 = null;// 类实例
            Simple ss1 = new Simple(), ss2 = new Simple(); //结构实例

            cs1.x = ss1.x = 5;
            cs1.y = ss1.y = 10;
            ss1.z = cs1;

            ss2 = ss1;
            ss2.z.x = 200;

            Console.WriteLine($"ss1.z.x is {ss1.z.x}");
            Console.WriteLine($"ss2.z.x is {ss2.z.x}");
        }
    }
}

image-20210822213209359

预定义的无参数构造函数对每个结构都存在,而且不能删除或重定义,但是,可以创建另外的构造函数,只要它们有参数.这一点和类非常不同,对于类,编译器只在没有其他构造函数声明时提供隐式的无参数构造函数.

调用一个构造函数,包括隐式无参数构造函数,要使用new运算符,这表明,即使不从堆中分配内存也要使用new运算符.

namespace LearningCSharp 
{

    struct Simple
    {
        public int x;public int y;

        public Simple(int a,int b)
        {
            x = a;
            y = b;
            Console.WriteLine("This is constructor");
        }
    }
    class Program
    {
        static void Main()
        {
            Simple s1 = new Simple();
            Simple s2 = new Simple(5, 10);

            Console.WriteLine($"{s1.x},{s1.y}");
            Console.WriteLine($"{s2.x},{s2.y}");

        }
    }
}

image-20210822223542992

也可以不使用new运算符创建结构的实例(对于类来说,必须通过new运算符来创建类实例), 然而,如果这样做,必须满足:

  • 在显示设置数据成员之后,才能使用它们的值;
  • 在对所有的数据成员赋值之后,才能调用任何函数成员

静态构造函数

与类类似,结构的静态构造函数创建并初始化静态数据成员,而且不能引用实例成员.

以下两种行为,任意一种发生之前,将会调用静态构造函数:(1)调用显式声明的构造函数(2)引用结构的静态成员.

结构是密封的

结构总是隐式密封的,因此,不能从它们派生其他结构,由于结构不支持继承,因此不能在结构成员声明时使用protected,internal,abstract,virtual.

结构作为返回值和参数

  • 返回值:当结构作为返回值时,将创建它的副本,并从函数成员返回
  • 值参数:当结构被用作值参数时,将创建实参结构的副本.该副本用于方法的执行中.
  • ref和out参数:如果把一个结构用作ref,out参数,传入方法的是该结构的一个引用,这样就可以修改其数据成员.
posted @ 2021-08-22 23:06  JohnYang819  阅读(134)  评论(0编辑  收藏  举报