类和结构/扩展方法

类和结构

类和结构都是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法,类定义类的每个对象(实例)可以包含什么数据和功能

类和机构的区别在于他们在内存中的存储方式/访问方式,类是存储在堆(heap)上的引用类型,结构是存储在栈(stack)上的值类型,并且结构不支持继承,从语法上来看结构与类非常相似,主要区别是结构使用关键字struct声明,而类使用class声明

类中的数据和函数称为类的成员,成员的可访问性可以是public/protected/internal protected/private/internal

数据成员:数据成员是包含类的数据,其中包括了字段/常量/事件成员(事件是类的成员,在发生某些行为时,可以让对象通知调用方,"事件处理程序"),数据成员可以是静态数据,类成员总是实例成员,除非使用static显式声明

函数成员:函数成员提供了操作类中数据的某些功能,包括方法/属性/构造函数/析构函数/运算符/索引器   

  • 方法:方法是与类相关的函数,,默认为实例成员,使用static可以定义静态方法
    • 定义语法
    • [modifiers] return_type MethodName([parameters]){
      
      }
    • 方法传参:参数可以通过引用或者值传递给方法,在变量通过引用传递时,被调用方法得到的变量引用或者说指向内存中变量的指针,在方法内部对变量进行的任何修改在退出方法后仍然有效,而如果变量通过值传递给方法,被调用的方法得到的是变量的一个相同副本,也就是说在方法退出后,对变量进行的修改将会丢失;在C#中,除非特别指定,否则所有的引用类型都通过引用传递,所有的值类型都通过值传递;这里需要注意的是:字符串的方式有所不同,因为字符串的不可变性(如果改变字符串的值就会创建一个全新的字符串),所以字符串无法采用一般引用类型的行为方式,在方法调用中,对字符串所做的任何改变都不会影响原始字符串

    • ref参数:用于将值参数通过引用传递给方法(该方法对对值所做的任何改变都会影响原值);ref参数在使用前必须被初始化,在调用时也需要添加ref关键字
    • out参数:ref参数可以将值参数通过引用的方式传递给方法,但是在使用前必须被初始化,而out参数提供同样的功能,但是可以不初始化值
    • 命名参数:参数一般需要按照定义的顺序传递给方法,使用命名参数可以按照任意顺序传递
    • 可选参数:可以使用为参数添加默认值的方式来使用可选参数,需要注意:可选参数必须在所有参数的末尾
  • 属性:属性是可以从客户端访问的方法组,访问方式与访问类的公共字段类似,但C#中为读写类的属性提供了专用的语法,不必使用那些名称中嵌有Get或Set的方法;可以通过在属性中定义get/set访问器的方式来定义只读/只写属性,如果属性的get/set访问器中没有任何逻辑,可以使用自动实现的属性
  • 构造函数:构造函数是在实例化对象时自动调用的特殊函数,必须与类同名,且不能有返回类型,用于初始化字段的值
    • 构造函数:如果没有显式定义构造函数,编译器会默认创建一个无参的构造函数用来初始化值(引用类型为空引用,值类型为0,bool类型为false),但是如果显式定义了带参的构造函数,编译器就不会自动创建默认的构造函数
    • 静态构造函数:在类中存在一些静态字段或者属性,需要在第一次使用前,从外部数据源中初始化这些值,这时候可以通过静态构造函数实现,静态构造函数不能带任何参数,一个类也只能有一个静态构造函数,并且静态构造函数只能访问类的静态成员,无法访问类的实例成员;需要注意:加载类时执行静态构造函数,创建实例是执行实例构造函数
    • 构造函数初始化器
  • 析构函数:又称为终结器,类似于构造函数,也是与类同名,不同的是前面有一个"~"符号,在CLR检测到不再需要某个对象时调用它,终结器调用无法预测,由CLR管理
  • 运算符
  • 索引器:索引器允许对象以数组或集合的方式进行索引

 只读字段:常量的概念是包含一个不可修改值的变量,但是某些场景下,我需要有常量的功能,但是值在运行前是未知的,C#为这种情形提供了只读字段;只读字段只能在字段声明时或构造函数中赋值,不能在其他地方赋值,只读字段可以是静态字段.与const常量不同的是,如果要把只读字段设置为静态,就必须显式声明

结构

如果只需要一个小的数据结构,最好使用结构,

  • 结构的实例化可以不使用new
  • 结构不支持继承:结构不是为继承设计的,意味着结构不能继承另一个结构,例外是结构也派生于System.Object,意味着结构可以访问System.Object中的方法并且可以重写;结构的继承链是:结构->System.ValueType->System.Object
  • 结构的构造函数:为结构定义构造函数的方式与类定义构造函数方式相同,但是不允许定义无参的构造函数,C#中禁止在结构内定义无参构造函数;并且在结构声明中,除非字段被声明为 const 或 static,否则无法赋初始值
  • 结构是值类型:结构是会影响性能的值类型,为结构分配内存时速度非常快,因为它们是保存在栈上,在结构超出使用域时,删除的速度也很快,不需要等待垃圾回收(GC),但是需要注意:如果将结构赋值给另一个结构,结构的所有内容就会被复制,而对于类,则只复制引用

静态类

如果类中只包含了静态的方法和属性,该类就是静态的,静态类作用于类本身,不需要创建类的实例即可调用

Object类

之前说到,所有的.Net类都派生自System.Object,如果在定义时没有指定基类编译器就会假定该类派生自Object,实际意义在于除了使用自己定义的方法和属性外,还可以访问Object类定义的许多公有的受保护的成员方法,比如ToString()/GetHashCode/Equals/ReferenceEquals/Finalize等

扩展方法

在没有类的源代码的情况下,可以使用扩展方法来对类进行扩展,扩展方法是静态方法.需要注意:尽管扩展方法是静态方法,也需要使用标准的实例方法调用.同时类中的实例方法优化级高于扩展方法(同名情况下)

语法:第一个参数是要扩展的类型,放在this关键字后

public static class DateExtension
{
public static string Format(this DateTime date, string format = "yyyy-MM-dd HH:mm:ss") { return date.ToString(format); } }

 

转载于:https://www.cnblogs.com/GnailGnepGnaw/p/10601664.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值