当前位置:首页 > 全部子站 > 备课网 > 学院

C# 程序员参考--结构教学文章

来源:长理培训发布时间:2017-08-20 20:19:55

 本教程介绍结构的语法和用法。它还涉及类与结构之间的重大差异。

示例文件

请参见“结构”示例以下载和生成本教程中讨论的示例文件。

教程

此教程包括两个示例。第一个示例向您展示如何声明和使用结构,而第二个示例演示向方法传递实例时结构和类之间的差异。还向您介绍下列主题:

  • 结构与类
  • 堆还是堆栈?
  • 构造函数和继承
  • 结构上的属性

示例 1

本示例声明一个结构,它有三个成员:一个属性、一个方法和一个私有字段。本示例创建该结构的一个实例,并将其投入使用:

// struct1.cs



using System;



struct SimpleStruct



{



    private int xval;



    public int X



    {



        get 



        {



            return xval;



        }



        set 



        {



            if (value < 100)



                xval = value;



        }



    }



    public void DisplayX()



    {



        Console.WriteLine("The stored value is: {0}", xval);



    }



}







class TestClass



{



    public static void Main()



    {



        SimpleStruct ss = new SimpleStruct();



        ss.X = 5;



        ss.DisplayX();



    }



}

输出

The stored value is: 5

结构与类

结构可能看似类,但存在一些重要差异,应引起注意。首先,类为引用类型,而结构为值类型。使用结构,您可以创建行为类似内置类型的对象,同时享有它们的好处。

堆还是堆栈?

在类上调用“新建”(New) 运算符时,它将在堆上进行分配。但是,当实例化结构时,将在堆栈上创建结构。这样将产生性能增益。而且,您不会像对待类那样处理对结构实例的引用。您将直接对结构实例进行操作。鉴于此原因,向方法传递结构时,结构将通过值传递,而不是作为引用传递。

示例 2

本示例展示当向方法传递结构时,将传递该结构的副本,而传递类实例时,将传递一个引用。

// struct2.cs



using System;







class TheClass



{



    public int x;



}







struct TheStruct



{



    public int x;



}







class TestClass



{



    public static void structtaker(TheStruct s)



    {



        s.x = 5;



    }



    public static void classtaker(TheClass c)



    {



        c.x = 5;



    }



    public static void Main()



    {



        TheStruct a = new TheStruct();



        TheClass b = new TheClass();



        a.x = 1;



        b.x = 1;



        structtaker(a);



        classtaker(b);



        Console.WriteLine("a.x = {0}", a.x);



        Console.WriteLine("b.x = {0}", b.x);



    }



}

输出

a.x = 1



b.x = 5

代码讨论

本示例的输出表明:当向 classtaker 方法传递类实例时,只更改了类字段的值。但是向 structtaker 方法传递结构实例并不更改结构字段。这是因为向 structtaker 方法传递的是结构的副本,而向 classtaker 方法传递的是对类的引用。

构造函数和继承

结构可以声明构造函数,但它们必须带参数。声明结构的默认(无参数)构造函数是错误的。结构成员不能有初始值设定项。总是提供默认构造函数以将结构成员初始化为它们的默认值。

使用 New 运算符创建结构对象时,将创建该结构对象,并且调用适当的构造函数。与类不同的是,结构的实例化可以不使用 New 运算符。如果不使用“新建”(new),那么在初始化所有字段之前,字段将保持未赋值状态,且对象不可用。

对于结构,不像类那样存在继承。一个结构不能从另一个结构或类继承,而且不能作为一个类的基。但是,结构从基类对象继承。结构可实现接口,而且实现方式与类实现接口的方式完全相同。以下是结构实现接口的代码片段:

interface IImage



{



    void Paint();



}







struct Picture : IImage



{



    public void Paint()



    {



         // painting code goes here



    }



    private int x, y, z;  // other struct members



}

结构上的属性

通过使用属性可以自定义结构在内存中的布局方式。例如,可以使用StructLayout(LayoutKind.Explicit) 和 FieldOffset 属性创建在 C/C++ 中称为联合的布局方式。

using System.Runtime.InteropServices;



[StructLayout(LayoutKind.Explicit)]



struct TestUnion 



{



    [FieldOffset(0)] 



    public int i;



    [FieldOffset(0)] 



    public double d;



    [FieldOffset(0)] 



    public char c;



    [FieldOffset(0)] 



    public byte b1;



}

在上一个代码段中,TestUnion 的所有字段都从内存中的同一位置开始。

以下是字段从其他显式设置的位置开始的另一个示例:

 

[1] [2] 下一页  

 

using System.Runtime.InteropServices; [StructLayout(LayoutKind.Explicit)] struct TestExplicit { [FieldOffset(0)] public long lg; [FieldOffset(0)] public int i1; [FieldOffset(4)] public int i2; [FieldOffset(8)] public double d; [FieldOffset(12)] public char c; [FieldOffset(14)] public byte b1; }

i1 和 i2 这两个 int 字段共享与 lg 相同的内存位置。使用平台调用时,这种结构布局控制很有用。

结束语

结构使用简单,并且有时证明很有用。但要牢记:结构在堆栈中创建,并且您不是处理对结构的引用,而是直接处理结构。每当需要一种将经常使用的类型,而且大多数情况下该类型只是一些数据时,结构可能是最佳选择。

 

 

上一页  [1] [2] 

责编:杨粟梅

发表评论(共0条评论)
请自觉遵守互联网相关政策法规,评论内容只代表网友观点,发表审核后显示!

国家电网校园招聘考试直播课程通关班

  • 讲师:刘萍萍 / 谢楠
  • 课时:160h
  • 价格 4580

特色双名师解密新课程高频考点,送国家电网教材讲义,助力一次通关

配套通关班送国网在线题库一套

课程专业名称
讲师
课时
查看课程

国家电网招聘考试录播视频课程

  • 讲师:崔莹莹 / 刘萍萍
  • 课时:180h
  • 价格 3580

特色解密新课程高频考点,免费学习,助力一次通关

配套全套国网视频课程免费学习

课程专业名称
讲师
课时
查看课程
在线题库
面授课程更多>>
图书商城更多>>
在线报名
  • 报考专业:
    *(必填)
  • 姓名:
    *(必填)
  • 手机号码:
    *(必填)
返回顶部