第17节 字段、属性、索引器、常量

  • 字段
  • 属性(C#所特有的)
  • 索引器(概述)
  • 常量

类的成员

字段

  1. 什么是字段
    1)字段(field)是一种表示与对象或类型(类与结构体)关联的变量(为对象或类型存储数据)
    2)字段是类型的成员,旧称“成员变量”
    3)与对象关联的字段亦称“实例字段”
    4)与类型关联的字段称为“静态字段”,由static修饰

  2. 字段的声明
    1)参见C#语言定义文档
    2)尽管字段声明带有分号,但它不是语句
    3)字段的名字一定是名词

  3. 字段的初始值
    1)无显式初始化时,字段获得其类型的默认值,所以字段“永远都不会未被初始化”
    2)实例字段初始化的时机——对象创建时
    3)静态字段初始化的时机——类型被加载(load)时

  4. 只读字段
    为实例或类型保存一旦初始化之后就不希望再改变的值。
    1)实例只读字段:只有一次赋值的机会,在其构造器或者声明的时候进行里初始化。
    2)静态只读字段:只能在静态构造器里或者在声明的时候初始化。

举例:
实例只读字段:

class Program
{static void Main(string[] args){Student student = new Student(1);Console.WriteLine(student.ID);}
}class Student
{public readonly int ID;  //实例只读字段public int Age;public int Score;public static int AverageAge;public static int AverageScore;public static int Amount = 100;public Student(int id)  //在构造器里面初始化,并且之后不能进行修改{this.ID = id;}
}

静态只读字段

class Program
{static void Main(string[] args){Console.WriteLine(Brush.DefaultColor.Red);}
}struct Color
{public int Red;public int Green;public int Blue;
}class Brush
{public static readonly Color DefaultColor = new Color() { Red = 0, Green = 0, Blue = 0 };  //静态只读字段
}

静态构造器

class Brush
{public static readonly Color DefaultColor;static Brush() //静态构造器是static,而实例构造器是public{Brush.DefaultColor = new Color() { Red = 0, Green = 0, Blue = 0 };}
}

属性(C#所特有的)

什么是属性

  1. 属性(property)是一种用于访问对象或类型的特征的成员,特征反映了状态
  2. 属性是字段的自然扩展
    1)从命名上看,field更偏向于实例对象在内存中的布局,property更偏向于反应现实世界对象的特征
    2)对外:暴露数据,数据可以是存储在字段里的,也可以是动态计算出来的
    3)对内:保护字段不被非法值“污染”
  3. 属性由Get/Set方法对进化而来
  4. 又一个“语法糖”——属性背后的秘密

Get/Set方法

class Program
{static void Main(string[] args){try{Student stu1 = new Student();stu1.SetAge(20);Student stu2 = new Student();stu2.SetAge(20);Student stu3 = new Student();stu3.SetAge(20);int avgAge = (stu1.GetAge() + stu2.GetAge() + stu3.GetAge()) / 3;Console.WriteLine(avgAge);}catch (Exception ex){Console.WriteLine(ex.Message);}}
}class Student
{private int age; //字段,private 变量命名全用小写字母public int GetAge() //GetAge() 方法{return this.age;}public void SetAge(int value) //SetAge() 方法{if (value >= 0 && value <= 120){this.age = value;}else{throw new Exception("Age value has error!");}}
}

属性

class Program
{static void Main(string[] args){try{Student stu1 = new Student();stu1.Age = 20;Student stu2 = new Student();stu2.Age = 20;Student stu3 = new Student();stu3.Age = 20;int avgAge = (stu1.Age+stu2.Age+stu3.Age)/3;Console.WriteLine(avgAge);}catch(Exception ex){Console.WriteLine(ex.Message);}}
}class Student
{private int age; //Student类的字段public int Age  //Student类的属性{get{return this.age;}set{if(value>=0 && value<=120) //value是上下文关键字{this.age = value;}else{throw new Exception("Age value has error!");}}}
}

属性的声明

  1. 完整声明——后台(back)成员变量与访问器(注意使用code snippet 和 refactor 工具
    代码提示:propfull + 连续两下tab键(获得代码的框架)。

  2. 简略声明——只有访问器(查看IL代码)
    功能与公有的字段一样,不受保护!!为了传递数据使用
    代码提示:prop + 连续两下tab键(获得代码的框架)。

快速声明属性的三种方法:
1)完整声明:propfull + 连续两下tab键;
2)简略声明:prop + 连续两下tab键
3)高级版本的vs中才有:private int age;将光标放置在 age 字段的中间,点击Ctrl+r、e,应用。

注:完整声明与简略声明的最大区别在于getter和setter的不同。

  1. 动态计算值的属性(不懂)
  2. 注意实例属性和静态属性
    实例属性:通过数据反应实例当前的状态
    静态属性:通过数据反应类型当前的状态
  3. 属性的名字一定是名词
  4. 只读属性——只有getter没有setter
    1)尽管语法上正确,几乎没有人使用“只写属性”,因为只写属性的主要目的是通过向外暴露数据而表示对象/类型的状态
    2)只读方法:只有 get 没有 set

注:如果在 set 方法前面加 private ,则该方法只能在其所属的类里面进行访问,外界不能进行访问,但是该属性不是只读属性

属性与字段的关系

  1. 一般情况下,它们都用于表示实体(对象或类型)的状态
  2. 属性大多数情况下是字段的包装器(wrapper)
  3. 建议:永远使用属性(而不是字段)来暴露数据,即字段永远都是private或protected的

索引器(概述)

什么是索引器
索引器(indexer)是这样一种成员:它是对象能够与数组相同的方式(即使用下标)进行索引。一般用在集合类型!!!

索引器的声明
参见 C# 语言定义文档
声明索引器:
代码提示:index + 连续两下 tab 键

注:声明静态索引器

class Program
{static void Main(string[] args){Student stu = new Student();stu["Math"] = 90;var mathScore = stu["Math"];Console.WriteLine(mathScore.GetType().FullName);Console.WriteLine(mathScore);}
}class Student
{private Dictionary<string, int> scoreDictionary = new Dictionary<string, int>();public int? this[string subject]  //声明索引器,返回值的类型是可空的整型,并用string类型进行索引{get{if (this.scoreDictionary.ContainsKey(subject)){return this.scoreDictionary[subject];}else{return null;}}set{if (value.HasValue == false) //判断可空类型的变量是不是真的有值{throw new Exception("Score cannot be null");}if (this.scoreDictionary.ContainsKey(subject)){this.scoreDictionary[subject] = value.Value; //可空类型的 value.Value 才是它真正的值}else{this.scoreDictionary.Add(subject, value.Value);}}}
}

常量

什么是常量

  1. 常量(constant)是表示常量值(即,可以在编译时计算的值)的类成员
  2. 常量隶属于类型而不是对象,即没有“实例常量”
    1)“实例常量”的角色由只读实例字段来担当
  3. 注意区分成员常量与局部常量
    成员常量:类型的成员
    局部常量:用于参与组成方法体中的算法

常量的声明

各种“只读”的应用场景

  1. 为了提高程序可读性和执行效率——常量
  2. 为了防止对象的值被改变——只读字段
  3. 向外暴露不允许修改的数据——只读属性(静态或非静态),功能与常量有一些重叠
  4. 当希望成为常量的值其类型不能被常量声明接受时(类/自定义结构体)——静态只读字段

第 17 节 字段、属性、索引器、常量相关推荐

  1. 【笔记】《C#高效编程改进C#代码的50个行之有效的办法》第1章C#语言习惯(1)--属性的特性以及索引器(SamWang)...

    ************************************************************************** 书名:<C#高效编程改进C#代码的50个行之 ...

  2. C#索引器的实现、索引器和属性的异同对比,这些技能你get到了嘛?

    目录 什么是索引器? 如何声明索引器? 索引器和属性的异同对比 索引器实例分析 Hello!大家好,我是努力赚钱买生发水的灰小猿! 最近在用C#做开发的时候要用到索引函数,所以今天就在这里和小伙伴记录 ...

  3. C#语法小知识(六)属性与索引器

    属性是一种成员,它提供灵活的机制来读取.写入或计算私有字段的值. 属性可用作公共数据成员,但它们实际上是称为"访问器"的特殊方法. 这使得可以轻松访问数据,还有助于提高方法的安全性 ...

  4. c#初学-索引器get和set的使用(泛型类)

    索引器允许类或结构的实例就像数组一样进行索引.索引器类似于属性,不同之处在于它们的访问器采用参数. 在下面的示例中,定义了一个泛型类,并为其提供了简单的 get 和 set 访问器方法(作为分配和检索 ...

  5. C#锐利体验-第八讲 索引器与操作符重载(转)

    第八讲 索引器与操作符重载 南京邮电学院 李建忠(cornyfield@263.net) 索引 C#锐利体验 "Hello,World!"程序 C#语言基础介绍 Microsoft ...

  6. 字段,属性,索引器,常量

    这四种成员都是用来表达数据的. 1.字段(field) (1)什么是字段 字段是一种表示与对象或类型(类与结构体)关联的变量.为一个对象或类型存储数据.多个字段组合起来可以表示对象或类型的状态. 字段 ...

  7. java类中定义索引器,C#面向对象基础——字段、属性和索引器

    关于面向对象编程,在很多语言里面都出现过,最常用的如java和c++, C#语言关于面向对象编程的规范,我觉得介于上面两者之间,我的理解是它比较偏向c++,或许是因为跟它的析构函数有关系,像java有 ...

  8. 【Kotlin】属性 与 幕后字段 ( 属性声明 | 属性初始化器 | 属性访问器 | field 属性幕后字段 | lateinit 延迟初始化属性 )

    文章目录 I . 属性 字段 总结 II . 属性声明 III . 属性初始化器 IV . get / set 属性访问器 V . 属性幕后字段 field VI . 变量和常量的区别 VII . 延 ...

  9. C# 属性、索引器(二)

    属性 using System; namespace runoob {public abstract class Person{public abstract string Name{get;set; ...

最新文章

  1. 联合体union和大小端(big-endian、little-endian)
  2. Numpy的介绍和优势
  3. 基于K-gram的winnowing特征提取剽窃查重检测技术(概念篇)
  4. redis操作大数据
  5. 数据结构与算法 | 用队列实现栈
  6. USACO 1.1 Your Ride Is Here
  7. Android 清除png图片的白色背景
  8. Redis基础-下载安装配置
  9. vue-cli3.0 初体验
  10. 经纬度转换为平面坐标
  11. HDOJ--1875--畅通工程再续
  12. 学校为什么要单位接收函_学校就快要截止收档案接收函了!你开始处理没?
  13. 使用XMLHttpRequest
  14. JAVASE学习总结(20):字符串相关的类--StringBuffer
  15. 网站免费推广100种方法
  16. android edittext过滤空格,关于android:在EditText中拦截空格键的问题
  17. arduino中print()跟write()最大区别和注意事项 (最详细)
  18. python快速幂算法解决大数取模
  19. RN-Flex Box---基础
  20. Arduino与FreeRTOS-守护任务(Gatekeeper Task)

热门文章

  1. 做闲鱼两年了,bug不少
  2. mysql数据库计算全部女生_mysql数据库基础操作大全(小白必看)
  3. 怎样通过微信查找特殊服务器,微信支持多设备同时在线 还有哪些你不知道的微信隐藏功能...
  4. 闲话网名之“+黑色***+”
  5. vue 区号-电话 的校验方式
  6. mobiledevice什么意思_AppleMobileDevice是什么
  7. Luminar AI绿色便携版
  8. 如何用Luminar 3图像后期处理软件制作与众不同的黑白照片?
  9. 错误代码0x800C0133错误问题的解决方案
  10. DC-3渗透实战(详细过程)