C# 程序员参考--结构教程

参考|程序|程序员|教程

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

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

示例 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 = 1b.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 的所有字段都从内存中的同一位置开始。

  以下是字段从其他显式设置的位置开始的另一个示例: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 相同的内存位置。使用平台调用时,这种结构布局控制很有用。

结束语

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

时间: 2024-10-30 03:22:27

C# 程序员参考--结构教程的相关文章

最让程序员懊恼的 10 件事

10. 注释说明"是什么",而不是"为什么" 入门级编程课程教导学生要学会频繁且尽早地注释.不可否认在学习编程的起步阶段这方法的确是相当有效的(即使看到最简单的代码行都像天书).然而许多程序员即使已经从一只小菜鸟长大成一位计算机牛人,也还是把这个习惯给延续了下来. r = n / 2; // Set r to n divided by 2 // Loop while r – (n/r) is greater than t while (abs ( r – (n/r)

《C和C++程序员面试秘笈》——1.10 标准头文件的结构

1.10 标准头文件的结构 C和C++程序员面试秘笈为什么标准头文件都有类似以下的结构? 考点: 标准头文件中一些通用结构的理解 出现频率: #ifndef __INCvxWorksh #define __INCvxWorksh #ifdef __cplusplus extern "C" { #endif /*...*/ #ifdef __cplusplus } #endif #endif /* __INCvxWorksh */``` [解析] 显而易见,代码第1.2.10行的作用是防

程序员的.NET时代(一)

程序|程序员 技术总是在不断发展,微软.NET平台经历了三年时间的历程,已经被广大开发人员所接受.我们利用Visual Studio.NET,可以快速.高效地进行Windows Form和Web Form的应用开发..NET是一个全新的概念,.NET代表了一个集合.一个环境.一个编程的基本结构,作为一个平台来支持下一代的互联网,因为我们相信世界不会倒退到集中计算的主机模式下.在XML Web Service技术逐渐成熟的时候,软件可被当作一种服务,支持新的设备,这些设备包括PC.移动电话.PDA

[转]程序员资料整理

前言 一些主流技术资源整理. 目录 资料篇 技术站点 必看书籍 大牛博客 GitHub篇 工具篇 平台工具 常用工具 第三方服务 爬虫相关(好玩的工具) 安全相关 Web服务器性能/压力测试工具/负载均衡器 大数据处理/数据分析/分布式工具 Web前端 语言篇 Scala Java Python Swift .NET C & C++ 其他 游戏开发相关 日志聚合,分布式日志收集 RTP,实时传输协议与音视频 资料篇 技术站点 在线学习:Coursera.edX.Udacity.MIT公开课.MO

程序员技术练级攻略

月光博客6月12日发表了<写给新手程序员的一封信>,翻译自<An open letter to those who want to start programming>,我的朋友(他在本站的id是Mailper)告诉我,他希望在酷壳上看到一篇更具操作性的文章.因为他也是喜欢编程和技术的家伙,于是,我让他把他的一些学习Python和Web编程的一些点滴总结一下.于是他给我发来了一些他的心得和经历,我在把他的心得做了不多的增改,并根据我的经历增加了"进阶"一节.这是

程序员必读书单(转)

  原文链接:http://lucida.me/blog/developer-reading-list/ 关于 本文把程序员所需掌握的关键知识总结为三大类19个关键概念,然后给出了掌握每个关键概念所需的入门书籍,必读书籍,以及延伸阅读.旨在成为最好最全面的程序员必读书单. 前言 Reading makes a full man; conference a ready man; and writing an exact man. Francis Bacon 优秀的程序员应该具备两方面能力: 良好的

程序员必读书单

关于 本文把程序员所需掌握的关键知识总结为三大类19个关键概念,然后给出了掌握每个关键概念所需的入门书籍,必读书籍,以及延伸阅读.旨在成为最好最全面的程序员必读书单. 前言 Reading makes a full man; conference a ready man; and writing an exact man. Francis Bacon 优秀的程序员应该具备两方面能力: 良好的程序设计能力: 掌握常用的数据结构和算法(例如链表,栈,堆,队列,排序和散列): 理解计算机科学的核心概念

[转载] 陈皓——程序员技术练级攻略

          PS:原文出自酷壳上的陈皓对程序员从入门到精通的攻略,让你感受一下真正的大神吧!又是阿里人,他的文章真心不错,希望对你也有用.原文地址:http://coolshell.cn/articles/4990.html           陈皓酷壳博客地址:    http://coolshell.cn/haoel                陈皓CSDN博客地址: http://blog.csdn.net/haoel 个人简介 15年软件开发相关工作经验,8年以上项目和团队管理

程序员练级攻略

(本文转自coolshell大神的博客)   月光博客6月12日发表了<写给新手程序员的一封信>,翻译自<An open letter to those who want to start programming>,我的朋友(他在本站的id是Mailper)告诉我,他希望在酷壳上看到一篇更具操作性的文章.因为他也是喜欢编程和技术的家伙,于是,我让他把他的一些学习Python和Web编程的一些点滴总结一下.于是他给我发来了一些他的心得和经历,我在把他的心得做了不多的增改,并根据我的经