C#基础语法:结构和类区别详解

结构和类很相似,也可以包含数据成员和函数成员,但是与类不同,结构是一种值类型,(我们可以理解为一种特殊的值类型所以不存在继承的问题)为其分配数据不需要从托管堆中分配存储器。结构类型的变量直接包含了该结构的数据,而类类型的变量所包含的只是对相应对象的一个引用。

 下面总结一下结构和类的不同:

1.结构是值类型,对结构类型的变量赋值将创建所赋值的一个副本。
2.结构实例的默认值不是null,而是具有默认值的初始值。
3.在结构和类中this的意义不一样。
4.结构不支持继承(所以结构成员的声明可访问性不能是protected,protected internal,结构中的函数成员不能是abstract 或者virtual,所以在结构中override修饰符只适用于重写从System.ValueType继承的方法)但是可以实现接口。
5.在结构中实例字段声明中不能含有变量的初始值设定项
6.在结构中不能声明无参数的实例构造函数。
7.在结构中不能声明析构函数。

测试区别特性代码:

using System;
namespace StructAndClass
{
  struct SPoint
  {
    public int x, y;
    public SPoint(int x, int y)
    {
      this.x = x;
      this.y = y;
    }
  }
  class CPoint
    {
      public int x, y;
      public CPoint(int x, int y)
      {
        this.x = x;
        this.y = y;
      }
    }
  class Test
  {
    public static void Main()
    {
      SPoint sp1 = new SPoint(2, 5);
      Console.WriteLine("结构/sp1初始值:");
      Console.WriteLine("sp1.x={0}", sp1.x);
      SPoint sp2 = sp1;
      Console.WriteLine("sp1=sp2后:");
      Console.WriteLine("sp1.x={0}");
      Console.WriteLine("sp1.x={0}", sp1.x);
      Console.WriteLine("sp2.x={0}", sp2.x);
      sp1.x = 5;
      Console.WriteLine("再次改变sp1的值后:");
      Console.WriteLine("sp1.x={0}", sp1.x);
      Console.WriteLine("sp2.x={0}", sp2.x);
      Console.WriteLine("============================");
      CPoint cp1 = new CPoint(2,5);
      Console.WriteLine("类/cp1初始值:");
      Console.WriteLine("cp1.x={0}", cp1.x);
      CPoint cp2 = cp1;
      Console.WriteLine("cp1=cp2后:");
      Console.WriteLine("cp1.x={0}", cp1.x);
      Console.WriteLine("cp2.x={0}", cp2.x);
      cp1.x = 5;
      Console.WriteLine("再次改变cp1的值后:");
      Console.WriteLine("cp1.x={0}", cp1.x);
      Console.WriteLine("cp2.x={0}", cp2.x);
      Console.ReadKey();
    }
  }
}

对于结构,即使没有new运算符声明的结构变量也是有效的,结构虽然不能声明无参数的实力构造函数,但是它其实隐式的包含了一个无参数的构造函数:而且在结构的所有字段没有明确赋值之前,不能调用结构的实例函数成员。在结构的构造函数中应该给所有的字段赋值。例如:

struct DC
  {
    public int x, y;
    public int X
    {
      set
      {
        x = value;
      }
      get
      {
        return x;
      }
    }
    public int Y
    {
      set
      {
        y = value;
      }
      get
      {
        return y;
      }
    }
    public DC(int x,int y)
    {
      this.x = x;
      this.y = y;
    }
  }
  struct RDC
  {
    public int x, y;
    public int X
    {
      set
      {
        x = value;
      }
      get
      {
        return x;
      }
    }
    public int Y
    {
      set
      {
        y = value;
      }
      get
      {
        return y;
      }
    }
    public RDC(int x, int y)
    {
      this.x = x;
      this.y = y;
    }
  }
  class Test
  {
    public static void Main()
    {
      DC dc=new DC();
      dc.x = 3;
      dc.y = 5;
      Console.WriteLine("已经对x,y初始化后:");
      Console.WriteLine("此时可以访问和修改dc.X={0}的值",dc.X);
      Console.WriteLine("我在这里创建了一个DC的复制结构RDC/n并且不对x,y初始化就会报错");
      RDC rdc;
       rdc.y = 5;//可以编译通过
       rdc.X = 3;//这里就会出错,不能编译通过
      Console.WriteLine("=======test over================");
     }
  }

在结构的实例构造函数内,this 相当于一个结构类型的 out 参数,(必须在内部对它明确赋值)而在结构的实例函数成员内,this 相当于一个结构类型的 ref 参数。在这两种情况下,this 本身相当于一个变量,因而有可能对该函数成员调用所涉及的整个结构进行修改(如对 this 赋值,或者将 this 作为 ref 或 out 参数传递)。例如:(引用上面的例子)

struct DC
  {
    public int x, y;
    public int X
    {
      set
      {
        x = value;
      }
      get
      {
        return x;
      }
    }
    public int Y
    {
      set
      {
        y = value;
      }
      get
      {
        return y;
      }
    }
    public DC(int x,int y)
    {
      X= x;//这里就是错的
      Y = y;//会提示没有给this对象的所有字段赋值
    }
  }
(0)

相关推荐

  • 理解C#中参数的值和引用以及传递结构和类引用的区别

    值与引用参数之间的区别: 在 C# 中,既可以通过值也可以通过引用传递参数.在调用环境中通过引用传递参数允许函数成员(方法.属性.索引器.运算符和构造函数)更改参数的值,并保持该更改.若要通过引用传递参数,请使用 ref 或 out 关键字. 下面的示例阐释值与引用参数之间的区别: class Program { static void Main(string[] args) { int arg; // Passing by value. // The value of arg in Main

  • C#中类与结构的区别实例分析

    类与结构是C#程序设计中基本的数据类型,而初学者往往不能很好的分清二者之间的区别.本文就以附带实例形式加以说明.具体如下: 一.基本概念: 类:引用类型,存储在堆中,栈中存储引用地址,在方法的传输中只是传输地址的引用,修改指向的对象会影响原有对象的值,传输中消耗内存小. 结构:值类型,存储在堆栈中,传输过程中传输整个对象的副本,修改指向对象的值不会影响原有的对象,传输中消耗内存大. 二.实例代码如下: class Program { static void Main(string[] args)

  • 深入c# 类和结构的区别总结详解

    类和结构的区别:1.一个是引用类型一个是值类型Class是引用类型,继承自System.Object类Struct是值类型,继承自System.ValueType类,因此不具有多态性因为结构是值类型,所以结构之间赋值可以创建新的结构,复制包含结构的变量时,讲复制所有的数据,对新的副本所作的修改都不会改变旧副本的数据,而类是引用类型,类之间的赋值只是复制引用.2. 继承性的区别Class支持继承,可以继承自类和接口,是完全可扩展的,除非声明sealed.否则类可以继承自其它的类的接口,自身也能被继

  • 基于c# 类、接口、结构的联系与区别详解

    一.C#类与结构的差别1. 值类型与引用类型结构是值类型:值类型在堆栈上分配地址,所有的基类型都是结构类型,例如:int 对应System.int32 结构,string 对应 system.string 结构 ,通过使用结构可以创建更多的值类型类是引用类型:引用类型在堆上分配地址堆栈的执行效率要比堆的执行效率高,可是堆栈的资源有限,不适合处理大的逻辑复杂的对象.所以结构处理作为基类型对待的小对象,而类处理某个商业逻辑因为结构是值类型所以结构之间的赋值可以创建新的结构,而类是引用类型,类之间的赋

  • 浅析C#中结构与类的区别

    一. 结构:值类型,存储在堆栈中,位于计算机的内存逻辑区域中 类   :引用类型,存储在堆中,位于计算机内存的不同逻辑位置 二. 较小的数据使用结构: 将一个结构值传递到方法时,传递的是整个数据结构: 传递一个类,实际上是将引用传递到对象,即只有内存地址: 对结构修改,改变的是结构的副本,这是值类型工作方式的定义:传递值的副本: 传递一个引用到类本身意味着在类中修改值,实际上改变的是原始对象: 三.代码例子 1.新建 PointClass.cs namespace StructAndClass

  • C#基础语法:结构和类区别详解

    结构和类很相似,也可以包含数据成员和函数成员,但是与类不同,结构是一种值类型,(我们可以理解为一种特殊的值类型所以不存在继承的问题)为其分配数据不需要从托管堆中分配存储器.结构类型的变量直接包含了该结构的数据,而类类型的变量所包含的只是对相应对象的一个引用.  下面总结一下结构和类的不同: 1.结构是值类型,对结构类型的变量赋值将创建所赋值的一个副本. 2.结构实例的默认值不是null,而是具有默认值的初始值. 3.在结构和类中this的意义不一样. 4.结构不支持继承(所以结构成员的声明可访问

  • Java基础语法之二维数组详解

    一.二维数组 进入正题之前.首先为了便于大家理解,我画了一个图: xx枪战游戏中, 我是一个刚刚注册账号的小白,系统送了我两把枪,此时,我的武器库只有这么一层(可以理解为一位数组,枪就是对应的数组中对应的元素) 经过艰苦卓绝的战斗,终于有了一笔钱,现在我打算配置好的游戏装备,我现在有了一个枪柜,它可以存放三层的枪械,每一层都可以放多把武器(这个就是二维数组,有多层,每层都是一个一维数组) 随着游戏时长和我的高超技术,获取游戏装备的效率越来越高了,一个枪柜已经存不下了,于是,我就有了多个枪柜(这个

  • Java基础类库之StringBuffer类用法详解

    StringBuffer类 String类是在所有开发项目开发之中一定会使用的一个功能类,并且这个类拥有如下功能 每个字符串的常量都属于一个String类匿名对象,并且不能修改: String类有两个常量池:静态常量池.运行常量池: String类对象实例化建议直接使用赋值的形式完成,这样可以直接将对象保存在对象池中方便下次重用: 虽然String类很好用,但是我们发现它也有弊端,就是内容不允许频繁修改,所以为了解决问题,我们提供了StringBuffer类 StringBuffer 并不像St

  • Java基础之枚举Enum类案例详解

    一.文章序言 Java中引用类型:数组.类.接口.枚举.注解 枚举这个既熟悉又陌生的东西具体再哪里可以使用呢? 什么是枚举? 枚举是一个引用类型,枚举就是一个规定了取值范围的变量类型. 枚举变量不能使用其他的数据,只能使用枚举中常量赋值.提高程序安全性: //格式: public enum 枚举名{ //枚举的取值范围 //枚举中可以生命方法 } 枚举的使用场景介绍? 1.最常见的情况如星期,相关变量我们会在Java里面重复使用,在这里我们就可以来定义一个叫做"星期"的枚举. publ

  • Python基础语法之变量与数据类型详解

    目录 一. 输出函数print 1.1 可以输出数字 1.2 可以输出字符串 1.3 可以输出表达式 1.4 可以输出至文件中 二. 变量与数据类型 2.1 整型 2.2 浮点型 2.3 字符串型 2.4 布尔型 3. 数据类型转换 3.1 int() 3.2 float() 3.3 str() 一. 输出函数print 在python中,print()是可以直接使用的输出函数,将数据输出到控制台上. 1. print函数的使用 1.1 可以输出数字 只要是数字都可以输出 # author: 爪

  • golang的基础语法和常用开发工具详解

    golang的基础语法 golang的基础语法和其他语言大部分都差别不大,如果我们有学习过其他语言,比如JavaScript,php,java,python等,有其他语言的语法基础,那么我们学习golang将更容易上手.那我们直接开始介绍golang的语法吧. 注释 注释分单行注释和多行注释.golang的注释和其他的开发语言的注释是一样的.双斜杠表示单行注释,/**/表示多行注释. // 单行注释这么开头 /* 多行注释 */ 定义包名 一般来说,使用开发工具的时候,包名是不需要手动输入的,开

  • C#基础语法:可空类型详解

    以下是System.Nullable<T>在FCL中的定义. [Serializable, StructLayout(LayoutKind.Sequential)] public struct Nullable<T> where T :struct { private Boolean hasValue= false; internal T value= default(T); public Nullable(T value) { this.value= value; this.ha

  • python基础之//、/与%的区别详解

    目录 示例代码如下: 附:一分钟看懂Python中的 // 和 / 和 % 的用法区别 总结 “ // ” 表示整数除法,返回整数 比如 7/3 结果为2 “ / ” 表示浮点数除法,返回浮点数 (即小数) 比如 8/2 结果为4.0 “ %” 表示取余数 比如7/4 结果为3 示例代码如下: pycharm环境下可直接运行使用 a = 321 b = a//100 c = a//10 % 10 d = a % 10 print("百位数是%d" % b) print("十位

  • Go语言基础语法之结构体及方法详解

    结构体类型可以用来保存不同类型的数据,也可以通过方法的形式来声明它的行为.本文将介绍go语言中的结构体和方法,以及"继承"的实现方法. 结构体类型 结构体类型(struct)在go语言中具有重要地位,它是实现go语言面向对象编程的重要工具.go语言中没有类的概念,可以使用结构体实现类似的功能,传统的OOP(Object-Oriented Programming)思想中的继承在go中可以通过嵌入字段的方式实现. 结构体的声明与定义: // 使用关键字 type 和 struct 定义名字

  • IOS 基础之nil,NULL,NSNULL区别详解

    IOS 基础之nil,NULL,NSNULL区别详解 ① nil:一般赋值给空对象. ② NULL:NULL 是一个通用指针(泛型指针). 一般赋值给 nil 之外的其他空值.如SEL等. ③ NSNULL:[NSNull null] 是一个对象,他用在不能使用 nil 的场合. 因为在 NSArray 和 NSDictionary 中 nil 有特殊的含义(表示列表结束),所以不能在集合中放入 nil 值.如要确实需要存储一个表示"什么都没有"的值,可以使用 NSNull 类.NSN

随机推荐