`
yangyou230
  • 浏览: 1644368 次
文章分类
社区版块
存档分类

.NET中class和struct的区别

 
阅读更多
1、引言

  提起class和struct,我们首先的感觉是语法几乎相同,待遇却天壤之别。历史将接力棒由面向过程编程传到面向对象编程,class和struct也背负着各自的命运前行。在我认为,struct英雄迟暮,class天下独行,最本质的区别是class是引用类型,而struct是值类型,它们在内存中的分配情况有所区别。由此产生的一系列差异性,本文将做以全面讨论。

  2、基本概念

  2.1、什么是class?

  class(类)是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段、属性、方法、属性、构造函数、索引器、操作符等。因为是基本的概念,所以不必在此详细描述,读者可以查询相关概念了解。我们重点强调的是.NET中,所有的类都最终继承自System.Object类,因此是一种引用类型,也就是说,new一个类的实例时,对象保存了该实例实际数据的引用地址,而对象的值保存在托管堆(managed heap)中。

  2.2、什么是struct?

  struct(结构)是一种值类型,用于将一组相关的信息变量组织为一个单一的变量实体 。所有的结构都继承自System.ValueType类,因此是一种值类型,也就是说,struct实例分配在线程的堆栈(stack)上,它本身存储了值,而不包含指向该值的指针。所以在使用struct时,我们可以将其当作int、char这样的基本类型类对待。

  

  图1

  3、相同点,不同点

  相同点:语法类似。

  不同点:

  ◆class是引用类型,继承自System.Object类;struct是值类型,继承自System.ValueType类,因此不具多态性。但是注意,System.ValueType是个引用类型。

  ◆从职能观点来看,class表现为行为;而struct常用于存储数据。

  ◆class支持继承,可以继承自类和接口;而struct没有继承性,struct不能从class继承,也不能作为class的基类,但struct支持接口继承。

◆class可以声明无参构造函数,可以声明析构函数;而struct只能声明带参数构造函数,且不能声明析构函数。因此,struct没有自定义的默认无参构造函数,默认无参构造器只是简单地把所有值初始化为它们的0等价值。

  ◆实例化时,class要使用new关键字;而struct可以不使用new关键字,struct在声明时就进行了初始化过程,所有的成员变量均默认为0或null。

  ◆class可以实抽象类(abstract),可以声明抽象函数;而struct为抽象,也不能声明抽象函数。

  ◆class可以声明protected成员、virtual成员、sealed成员和override成员;而struct不可以,但是值得注意的是,struct可以重载System.Object的3个虚方法,Equals()、ToString()和GetHashTable()。

  ◆class的对象复制分为浅拷贝和深拷贝,必须经过特别的方法来完成复制;而struct创建的对象复制简单,可以直接以等号连接即可。

  ◆class实例由垃圾回收机制来保证内存的回收处理;而struct变量使用完后立即自动解除内存分配。

  ◆作为参数传递时,class变量是以按址方式传递;而struct变量是以按值方式传递的。

  我们可以简单的理解,class是一个可以动的机器,有行为,有多态,有继承;而struct就是个零件箱,组合了不同结构的零件。其实,class和struct最本质的区别就在于class是引用类型,内存分配于托管堆;而struct是值类型,内存分配于线程的堆栈上。由此差异,导致了上述所有的不同点,所以只有深刻的理解内存分配的相关内容,才能更好的驾驭。本系列将再以后的内容中,将引用类型和值类型做以深入的比较和探讨,敬请关注。当然正如本文标题描述的一样,使用class基本可以替代struct的任何场合,class后来居上。虽然在某些方面struct有性能方面的优势,但是在面向对象编程里,基本是class横行的天下。

  那么,有人不免会提出,既然class几乎可以完全替代struct来实现所有的功能,那么struct还有存在的必要吗?答案是,至少在以下情况下,鉴于性能上的考虑,我们应该考虑使用struct来代替class:

  ◆实现一个主要用于存储数据的结构时,可以考虑struct。

  ◆struct变量占有堆栈的空间,因此只适用于数据量相对小的场合。

  ◆结构数组具有更高的效率。

  ◆提供某些和非托管代码通信的兼容性。

  所有这些是struct有一席之地的理由,当然也许还有其他的更多说法,只是我不知道罢了。

  4、经典示例

  4.1、小菜一碟

  下面以示例为说明,来阐述本文的基本规则,详细见注释内容。

  (1)定义接口

  

interface IPerson

  {

  void GetSex();

  }

(2)定义类

  

public class Person

  {

  public Person()

  {

  }

  public Person(string name, int age)

  {

  _name = name;

  _age = age;}

  private string _name;

  public string Name

  {

  get { return _name; }

  set { _name = value; }

  }

  private int _age;

  public int Age

  {

  get { return _age; }

  set { _age = value; }

  }

  }

(3)定义结构

  //可以继承自接口,不可继承类或结构

  

struct Family: IPerson

  {

  public string name;

  public int age;

  public bool sex;

  public string country;

  public Person person;

  //不可以包含显式的无参构造函数和析构函数

  public Family(string name, int age, bool sex, string country, Person person)

  {

  this.name = name;

  this.age = age;

  this.sex = sex;

  this.country = country;

  this.person = person;

  }

  //不可以实现protected、virtual、sealed和override成员

  public void GetSex()

  {

  if (sex)

  Console.WriteLine(person.Name + " is a boy.");

  else

  Console.WriteLine(person.Name + " is a girl.");

  }

  public void ShowPerson()

  {

  Console.WriteLine("This is {0} from {1}", new Person(name, 22).Name, country);

  }

  //可以重载ToString虚方法

  public override string ToString()

  {

  return String.Format("{0} is {1}, {2} from {3}", person.Name, age, sex ? "Boy" : "Girl", country);

  }

  }

(4)测试结构和类

  

  图2

  猜猜运行结果如何,可以顺便检查检查对这个概念的认识。

  4.2、.NET研究

  在.NET框架中,System.Drawing命名空间中的有些元素,如System.Drawing.Point就是实现为struct,而不是class。其原因也正在于以上介绍的各方面的权衡,大家可以就此研究研究,可以体会更多。另外,还有以struct实现的System.Guid。

  5、结论

  对基本概念的把握,是我们进行技术深入探索的必经之路,本系列的主旨也是能够从基本框架中,提供给大家一个通向高级技术的必修课程。本文关于class和struct的讨论就是如此,在.NET框架中,关于class和struct的讨论将涉及到对引用类型和值类型的认识,并且进一步将触角伸向变量内存分配这一高级主题,所以我们有必要来了解其运行机制,把握区别和应用场合,以便在平常的系统设计中把握好对这一概念层次的把握。

分享到:
评论

相关推荐

    .NET中接口与类的区别浅析

    大家应该都知道,在.Net中提供了接口,这个不同于Class或者Struct的类型定义。接口有些情况,看似和抽象类一样,因此有些人认为在.Net可以完全用接口来替换抽象类。其实不然,接口和抽象类各有长处和缺陷,因此往往...

    C++封装例程(class,struct,public,protected,private,friend)

    C++封装(class,struct,public,protected,private,friend)的博客例程。 https://blog.csdn.net/flysnow010/article/details/136907034

    C++面试题基础知识回顾

    2、C++中的 struct 和 class 有什么区别? 【参考答案】从语法上讲,class和struct做类型定义时只有两点区别: (一)默认继承权限。如果不明确指定,来自class的继承按照private继承处理,来自struct的继承按照...

    asp.net面试题3

    21.在.net中,配件的意思是? 答:程序集。...25.请详述在dotnet中类(class)与结构(struct)的异同? 答:Class可以被实例化,属于引用类型,是分配在内存的堆上的,Struct属于值类型,是分配在内存的栈上的.

    ADO.NetDemo_Class.zip

    对数据库表的增删改,C#源码,Students、StudentClass、StudentScore中封装的属性对应数据库中的表中的记录,StudentExt(前三个组合,为了组合查询),SQLHelper中封装的数据库连接断开方法,使用时记得修改成自己...

    .NET之美:.NET关键技术深入分析

    1.4.1从类型设计谈起,Class还是Struct 1.4.2数据不一致的问题 1.4.3 常量性和原子性 1.4.4避免外部类型对类型内部的访问 1.5本章小结 第2章C#中的泛型 2.1理解泛型 2.1.1 为什么要有泛型 2.1.2类型参数约束...

    .NET技术大全.c#学习指导书

    深入浅出.net学习,初学者必修教程. IS与AS ,接口和抽象类,特性和属性,CLASS和STRUCT ,base和this

    asp.net面试题

    11.详述.NET里class和struct的异同! class:放在 ? struct放在? struct值传递 类与结构有很多相似之处:结构可以实现接口,并且可以具有与类相同的成员类型。然而,结构在几个重要方面不同于类:结构为值类型而...

    CSharp 3.0 With the .NET Framework 3.5 Unleashed(english)

    The .NET Framework Class Library (FCL) 43 C# and Other .NET Languages 45 The Common Type System (CTS) 46 The Common Language Specification (CLS) 46 Summary 46 2 Getting Started with C# and ...

    .net面试题

    类(class)和结构(struct)的区别是什么?它们对性能有影响吗?

    net学习笔记及其他代码应用

    30.简要谈一下您对微软.NET 构架下remoting和webservice两项技术的理解以及实际中的应用。 答:WS主要是可利用HTTP,穿透防火墙。而Remoting可以利用TCP/IP,二进制传送提高效率。 31.公司要求开发一个继承System....

    【。net 专业】 面试题

    11.详述.NET里class和struct的异同! class:放在 ? struct放在? struct值传递 类与结构有很多相似之处:结构可以实现接口,并且可以具有与类相同的成员类型。然而,结构在几个重要方面不同于类:结构为值类型而不是...

    C#经典项目经验总结.doc

    1.String与string的区别 2.Convert.ToInt32(); 与Int32.Parse的区别 3. Subst命令的使用 ...c#中struct和class的区别 VS2008不能DEBUG(当前不会命中断点,还没有为该文档加载任何符号)解决方案

    .net(c#)中的new关键字详细介绍

    1、new一个class对象和new一个struct或者new一个enum有什么不同?  答:new一个class时,new完成2个内容:一是调用newobj命令为实例在托管堆中分配内存,二是调用构造函数实现对象初始化。  new一个struct时,new...

    Code Visualizer 4.57

    • Show each class and struct's inheritance, reference and use relation. • Show total class inheritance, reference and use relation. • Show whole project's statistics such as class count, function ...

    Professional C# 3rd Edition

    Operator Overloading Example: The Vector Struct 146 Which Operators Can You Overload? 153 User-Defined Casts 154 Implementing User-Defined Casts 155 Multiple Casting 161 Summary 165 Chapter 6: ...

    在一小时内学会 C#(txt版本)

    和 C++ 有所区别的是,C# 中没有单独的声明(头)和实现(CPP)文件。所有代码(类声明和实现)都放在扩展名为 cs 的单一文件中。 看看 C# 中的 Hello World 程序。 复制内容到剪贴板 代码: using System; ...

    c++ 面试题 总结

    说明上面三种描述的区别; 如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量; 如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。 (1)const char *p 一个...

    c#学习笔记.txt

    1, 结构(struct) 与 类(class) [attributes] [modifiers] struct identifier [:interfaces] body [;] 结构与类很相似,都表示可以包含数据成员和函数成员的数据结构。与类不同的是,结构是值类型并且不需要堆分配。...

    LuaBind 源码 (Lua增强库)

    LuaBind可以处理签名的区别只是const和非const的重载函数. 例如,如果如下的函数和类被注册: struct A { void f(); void f() const; }; const A* create_a();所有权转移 为了正确处理所有权转移问题,create_a()将...

Global site tag (gtag.js) - Google Analytics