一个正在奋斗中的IT民工

研究+交流+分享=提高

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

本示例演示在向方法传递结构时,传递的是该结构的副本,而在传递实例时,传递的是一个引用。

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

“折叠”图像示例

C#  “复制”图像复制代码
class TheClass
        {
        public string willIChange;
        }
        struct TheStruct
        {
        public string willIChange;
        }
        class TestClassAndStruct
        {
        static void ClassTaker(TheClass c)
        {
        c.willIChange = "Changed";
        }
        static void StructTaker(TheStruct s)
        {
        s.willIChange = "Changed";
        }
        static void Main()
        {
        TheClass testClass = new TheClass();
        TheStruct testStruct = new TheStruct();
        testClass.willIChange = "Not Changed";
        testStruct.willIChange = "Not Changed";
        ClassTaker(testClass);
        StructTaker(testStruct);
        System.Console.WriteLine("Class field = {0}", testClass.willIChange);
        System.Console.WriteLine("Struct field = {0}", testStruct.willIChange);
        }
        }
        
  “复制”图像复制代码
Class field = Changed
        Struct field = Not Changed

 

结构是使用 struct 关键字定义的,例如:

C#  “复制”图像复制代码
public struct PostalAddress
        {
        // Fields, properties, methods and events go here...
        }
        

结构与类共享大多数相同的语法,但结构比类受到的限制更多:

  • 在结构声明中,除非字段被声明为 const 或 static,否则无法初始化。

  • 结构不能声明默认构造函数(没有参数的构造函数)或析构函数。

由于结构的副本由编译器自动创建和销毁,因此不需要使用默认构造函数和析构函数。实际上,编译器通过为所有字段赋予默认值(参见默认值表(C# 参考))来实现默认构造函数。结构不能从类或其他结构继承。

结构是值类型。如果从结构创建一个对象并将该对象赋给某个变量,则该变量包含结构的全部值。复制包含结构的变量时,将复制所有数据,对新副本所做的任何修改都不会改变旧副本的数据。由于结构不使用引用,因此结构没有标识;无法区分具有相同数据的两个值类型实例。C# 中的所有值类型都继承自 ValueType,后者继承自 Object

编译器可以在一个称为装箱的过程中将值类型转换为引用类型。有关更多信息,请参见装箱和取消装箱(C# 编程指南)

“折叠”图像结构概述

结构具有以下特点:

  • 结构是值类型,而类是引用类型。

  • 与类不同,结构的实例化可以不使用 new 运算符。

  • 结构可以声明构造函数,但它们必须带参数。

  • 一个结构不能从另一个结构或类继承,而且不能作为一个类的基。所有结构都直接继承自 System.ValueType,后者继承自 System.Object

  • 结构可以实现接口。

  • 结构可用作可为 null 的类型,因而可向其赋 null 值。

使用结构

struct 类型适于表示 PointRectangleColor 等轻量对象。尽管可以将一个点表示为,但在某些情况下,使用结构更有效。例如,如果声明一个 1000 个 Point 对象组成的数组,为了引用每个对象,则需分配更多内存;这种情况下,使用结构可以节约资源。由于 .NET Framework 包含名为 Point 的对象,因此我们转而调用结构“CoOrds”。

C#  “复制”图像复制代码
public struct CoOrds
        {
        public int x, y;
        public CoOrds(int p1, int p2)
        {
        x = p1;
        y = p2;
        }
        }
        

声明结构的默认(无参数)构造函数是错误的。总是提供默认构造函数以将结构成员初始化为它们的默认值。在结构中初始化实例字段也是错误的。

如果使用 new 运算符创建结构对象,则会创建该结构对象,并调用适当的构造函数。与类不同,结构的实例化可以不使用 new 运算符。如果不使用 new,则在初始化所有字段之前,字段都保持未赋值状态且对象不可用。

对于结构,不像类那样存在继承。一个结构不能从另一个结构或类继承,而且不能作为一个类的基。但是,结构从基类 Object 继承。结构可实现接口,其方式同类完全一样。

与 C++ 不同,无法使用 struct 关键字声明类。在 C# 中,类与结构在语义上是不同的。结构是值类型,而类是引用类型。有关更多信息,请参见值类型

除非需要引用类型语义,否则系统将较小的类作为结构处理效率会更高。

“折叠”图像示例 1

说明

下面的示例演示使用默认构造函数和参数化构造函数的 struct 初始化。

代码

C#  “复制”图像复制代码
public struct CoOrds
        {
        public int x, y;
        public CoOrds(int p1, int p2)
        {
        x = p1;
        y = p2;
        }
        }
        
C#  “复制”图像复制代码
// Declare and initialize struct objects.
        class TestCoOrds
        {
        static void Main()
        {
        // Initialize:   
        CoOrds coords1 = new CoOrds();
        CoOrds coords2 = new CoOrds(10, 10);
        // Display results:
        System.Console.Write("CoOrds 1: ");
        System.Console.WriteLine("x = {0}, y = {1}", coords1.x, coords1.y);
        System.Console.Write("CoOrds 2: ");
        System.Console.WriteLine("x = {0}, y = {1}", coords2.x, coords2.y);
        }
        }
        

“折叠”图像输出

CoOrds 1: x = 0, y = 0

CoOrds 2: x = 10, y = 10

“折叠”图像示例 2

说明

下面举例说明了结构特有的一种功能。它在不使用 new 运算符的情况下创建 CoOrds 对象。如果将 struct 换成 class,程序将不会编译。

代码

C#  “复制”图像复制代码
public struct CoOrds
        {
        public int x, y;
        public CoOrds(int p1, int p2)
        {
        x = p1;
        y = p2;
        }
        }
        
C#  “复制”图像复制代码
// Declare a struct object without "new."
        class TestCoOrdsNoNew
        {
        static void Main()
        {
        // Declare an object:
        CoOrds coords1;
        // Initialize:
        coords1.x = 10;
        coords1.y = 20;
        // Display results:
        System.Console.Write("CoOrds 1: ");
        System.Console.WriteLine("x = {0}, y = {1}", coords1.x, coords1.y);
        }
        }
        

“折叠”图像输出

CoOrds 1: x = 10, y = 20 

posted on 2009-06-28 17:39  kidi  阅读(156)  评论(0)    收藏  举报