C#语言入门详解 第十七讲 (字段、属性、索引器、常量)

news2024/11/14 0:48:12

C#语言入门详解 第十七讲 (字段、属性、索引器、常量)

在C#语言中,类(或结构体)包含以下成员:
在这里插入图片描述

什么是字段

  • 字段(field)是一种表示与对象或类型(类与结构体)关联的变量
    字段是用来储存数据的,多个字段就可以描述对象的状态
  • 字段是类型的成员,旧称“成员变量”
  • 与对象关联的字段亦称“实例字段”
  • 与类型关联的字段称为“静态字段”,有static修饰
    internal class Program
    {
        static void Main(string[] args)
        {
			// 实例化一个对象
            Student stu1 = new Student();
            stu1.Age = 40;
            stu1.Score = 90;

            Student stu2 = new Student();
            stu2.Age = 24;
            stu2.Score = 60;
            
            Student.ReportAmount();  // >>>2
        }
    }

    class Student
    {
        // 定义实例字段(只有通过实例化之后才能被调用,不能通过类名调用)
        public int Age;
        public int Score;

        // 定义静态字段(通过类名调用,不能通过实例调用)
        public static int AverageAge;
        public static int AverageScore;
        public static int Amount;

        public Student()
        {
            Student.Amount++;
        }

        public static void ReportAmount()
        {
            Console.WriteLine(Student.Amount);
        }
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            List<Student> students = new List<Student>();
            for (int i = 0; i < 100; i++)
            {
                Student student = new Student();
                student.Age = 24;
                student.Score = i;
                students.Add(student);
            }

            int totalAge = 0;
            int totalScore = 0;
            foreach (Student student in students)
            {
                totalAge += student.Age;
                totalScore += student.Score;
            }
            Student.AverageAge = totalAge / Student.Amount;
            Student.AverageScore = totalScore / Student.Amount;

            Student.ReportAmount();  // >>>100
            Student.ReportAverageAge();  // >>>24
            Student.ReportAverageScore();  // >>>49
        }
    }

    class Student
    {
        // 定义实例字段(只有通过实例化之后才能被调用,不能通过类名调用)
        public int Age;
        public int Score;

        // 定义静态字段(通过类名调用,不能通过实例调用)
        public static int AverageAge;
        public static int AverageScore;
        public static int Amount;

        public Student()
        {
            Student.Amount++;
        }

        public static void ReportAmount()
        {
            Console.WriteLine(Student.Amount);
        }

        public static void ReportAverageAge()
        {
            Console.WriteLine(Student.AverageAge);
        }

        public static void ReportAverageScore()
        {
            Console.WriteLine(Student.AverageScore);
        }
    }

字段的声明

  • 参见C#语言定义文档
    字段必须包含在类型(类和和结构体)中,不能直接写在命名空间内,不能写在方法内(局部变量)
    字段声明最常用的两种形式
    只读字段的作用:用于保存一旦实例化后就不希望被修改的数据
public int Age; // 访问级别 变量类型 变量名;
public static int Amount; // 访问级别 static 变量类型 变量名;
// 建议在声明字段时就进行初始化
// 只读实例字段readonly
internal class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student(1);
            Console.WriteLine(student.ID); // >>>1
            student.ID = 2; // >>>无法编译,不能修改只读字段
        }
    }

    class Student
    {
        // 定义实例字段(只有通过实例化之后才能被调用,不能通过类名调用)
        public readonly int ID;  // 只读实例字段
        public int Age;
        public int Score;

        // 定义静态字段(通过类名调用,不能通过实例调用)
        public static int AverageAge;
        public static int AverageScore;
        public static int Amount;

        public Student(int ID)  // 动态初始化器,每次实例化都会执行
        {
            this.ID = ID;  // 初始化只读字段
        }
    }
// 静态只读字段
internal class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Brush.DefaultColor.Red);  // >>>0
        Console.WriteLine(Brush.DefaultColor.Green);  // >>>0
        Console.WriteLine(Brush.DefaultColor.Blue);  // >>>0
    }
}
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 };
    // 上面的语句和下面的作用是一致的
    public static readonly Color DefaultColor;
    static Brush()
    {
        Brush.DefaultColor = new Color() { Red = 0, Green = 0, Blue = 0 };
    }
}
  • 尽管字段声明带有分号,但不是语句
  • 字段的名字一定有名词

字段的初始值

  • 无显式初始值时,字段获得其类型的默认值,所以字段“永远都不会未被初始化”
  • 实例字段初始化的时机——对象创建时(每次创建实例都会执行一次)
  • 静态字段初始化的时机——类型被加载时(只执行一次)
  • 类的初始化也有静态初始化和动态初始化
    class Student
    {
        // 定义实例字段(只有通过实例化之后才能被调用,不能通过类名调用)
        public int Age;
        public int Score;

        // 定义静态字段(通过类名调用,不能通过实例调用)
        public static int AverageAge;
        public static int AverageScore;
        public static int Amount;

        public Student()  // 动态初始化器,每次实例化都会执行
        {
            
        }
        static Student()  // 静态初始化器,只在类加载时被执行
        {

        }
    }

只读字段

  • 实例只读字段
  • 静态只读字段

什么是属性

  • 属性(property)是一种用于访问对象或类型的特征的成员,特征反映了状态
  • 属性是字段的自然扩展
// 字段怎样向属性进化的??
// 将字段的访问级别由public改为private
// 变量名使用小写字母age
// 定义GetAge()和SetAge()方法,分别获取和设置属性值
internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Student stu1 = new Student();
                Student stu2 = new Student();
                Student stu3 = new Student();
                stu1.SetAge(20);
                stu2.SetAge(20);
                stu3.SetAge(200);
                double AverageAge = (stu1.GetAge() + stu2.GetAge() + stu3.GetAge()) / 3;
                Console.WriteLine(AverageAge);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

    class Student
    {
        private int age;
        public int GetAge()
        { 
            return this.age; 
        }
        public void SetAge(int age)
        {
            if (age > 0 & age < 100)
            {
                this.age = age;
            }
            else
            {
                throw new Exception("Age value has error!!");
            }

        }
    }
// 在C#中属性怎么创建??
// 定义名为Age的public变量
// 在变量名后加入{get{} set{}}
internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Student stu1 = new Student();
                Student stu2 = new Student();
                Student stu3 = new Student();
                stu1.Age = 20;
                stu2.Age = 20;
                stu3.Age = 20;
                double AverageAge = (stu1.Age + stu2.Age + stu3.Age) / 3;
                Console.WriteLine(AverageAge);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

    class Student
    {
        public int Age
        {
            get
            {
                return this.Age;
            }
            set
            {
                if (value > 0 & value < 100) // value是上下文关键字,在使用set时,value代指用户输入的指
                {
                    this.Age = value;
                }
                else
                {
                    throw new Exception("Age value has error!!");
                }
            }
        }
    }
    • 从命名上看,字段(field)更偏向于实例对象在内存中的布局,属性(property)更偏向于反映现实世界对象的特征
    • 对外:暴露数据,数据可以是存储在字段里的,也可以是动态计算出来的
    • 对内:保护字段不被非法值“污染”
  • 属性由Get/Set方法对进化而来
  • 又一个==“语法糖”==——属性背后的秘密

属性的声明

  • 完整声明——后台(back)成员变量与访问器(注意使用code snippet和refactor工具)
    • 在vs中完整声明的快捷方法,在VS中输入“propfull”并按两下tab键,会自动弹出下面代码,并可以通过tab键继续修改
private int myVar;
public int MyProperty
{
    get { return myVar; }
    set { myVar = value; }
}
  • 简略声明——只有访问器(查看IL代码)
    • 在vs中完整声明的简略声明,在VS中输入“prop”并按两下tab键,会自动弹出下面代码,并可以通过tab键继续修改
public int MyProperty { get; set; }
  • 动态计算值的属性
  • 注意实例属性的静态属性
  • 属性的名字一定是名词
  • 只读属性——只用getter没有setter
    • 尽管语法上正确,几乎没有人使用“只写属性”,因为属性的主要目的是通过向外暴露数据而表示对象/类型的状态

属性与字段的关系

  • 一般情况下,他们都用于实体的状态
  • 属性大多数情况下是字段的包装器
  • 建议:永远使用属性(而不是字段)来暴露数据,即字段永远都是private或protected的

什么是索引器

  • 索引器(indexer)是这样一种成员:它使对象能够用与数组相同的方式(即使用下标)进行索引
internal class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student();
            var mathScore = student["Math"];
            Console.WriteLine(mathScore==null); // >>>ture
            student["Math"] = 90;
            var newMathScore = student["Math"];
            Console.WriteLine(newMathScore); // >>>90
        }
    }

    class Student
    {
    	// 声明一个名为scoreDictionary的字典
        private Dictionary<string, int> scoreDictionary = new Dictionary<string, int>();
        // 创建索引器,快捷方式indexer+两下tab
        // int?表示可以是空值
        public int? this[string subject]
        {
            get { 
                /* return the specified index here */ 
                if (this.scoreDictionary.ContainsKey(subject))
                {
                    return scoreDictionary[subject];
                }
                else
                {
                    return null;
                }
            }
            set { 
                /* set the specified index to value here */
                if (value.HasValue == false)
                {
                    throw new Exception("Score cannot be null");
                }
                if (this.scoreDictionary.ContainsKey(subject))
                {
                    scoreDictionary[subject] = value.Value;
                }
                else
                {
                    this.scoreDictionary.Add(subject, value.Value);
                }
            }
        }

    }

索引器的声明

  • 参见C#语言定义文档
  • 注意:没有静态索引器

什么是常量

  • 常量(constant)是表示常量值(即,可以在编译时计算的值)的类成员
  • 常量隶属于类型而不是对象,即没有“实例常量”
    • “实例常量”的角色由只读实例字段来担当

常量的声明

public const double PI;

各种“只读”的应用场景

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/67649.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【传输层】概述、复用分用、UDP详解、UDP校验

文章目录传输层概述----为应用层服务TCP靠谱--大文件、时延大 与UDP不可靠--小文件、时延小传输层的寻址与端口------复用---应用层所有进程通过传输层再传输到网络层----------分用---------传输层从网络层收到数据后交付给指定应用程序套接字------Socket---IP&#xff1a;端…

足球冷知识:球队之间比分相同,怎么排名?

在足球比赛的小组赛中&#xff0c;往往会有胜、平、负三种结局&#xff0c;球队胜一场得三分、平一场得一分、输一场不得分。 如果球队积分相同&#xff0c;排名的时候&#xff0c;还会通过净胜球&#xff08;就是进球数减丢球数&#xff09;、相互交战的成绩、总进球数、球队累…

2023年天津美术学院专升本专业课报名缴费时间及考试安排

天津美术学院2023 年高职升本专业考试报名考试公告 一、报名时间 2022 年 12 月 9 日 10:00 至 12 月 12 日 17:00&#xff08;逾期不予补报&#xff0c;考生也不得再修改报名信息&#xff09; 注&#xff1a;每日 23:00 至次日 7:00 是报名系统维护时间&#xff0c;届时报名相…

搭建Python虚拟环境

搭建Python虚拟环境虚拟环境概述安装虚拟环境Windows环境下Linux环境下创建虚拟环境使用虚拟环境虚拟机环境下安装包PyCharm中使用虚拟环境虚拟环境 概述 为什么需要搭建Python的虚拟环境&#xff1f; 正常情况下&#xff0c;在一台电脑上, 想开发多个不同的项目, 需要用到同…

【GNN基础学习】图模块基本定义 || 图的邻接矩阵 || GNN中常见任务有哪些? || GNN消息传递方法 || 多层GCN有什么作用?

声明:仅学习使用~ 目录 一、图模块基本定义二、图的 邻接矩阵三、GNN中常见任务:点级别 任务、边级别 任务、图级别 任务。四、消息传递方法五、多层GCN的作用一、图模块基本定义 点、边、图。 对点的特征、边的特征、图的特征 等都要做重构。 借助于 图 这一结构,对事物…

39. 组合总和

39. 组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重…

C++并发编程

目录一、并发编程相关的基础概念1、操作系统&#xff08;Linux&#xff09;2、任务和通信3、多进程和多线程4、C中的多线程发展史二、pthread线程使用讲解和实战1、pthread基本使用2、线程的分离3、线程属性4、关于线程的几个值得注意的点三、线程的同步之互斥锁、读写锁、非阻…

MySQL 数据库主从复制

参考视频教程: https://www.bilibili.com/video/BV13a411q753?p172 参考博客: https://blog.csdn.net/main_Scanner01/article/details/124259050 1. 介绍 1.1 要点 主库(master): 负责增删改 从库(slave) : 负责查询 主从库关系: 一对多 1.2 步骤 ● master将改变记录到_…

宝塔部署node项目

宝塔linux&#xff1a;是一个linux运维面板&#xff0c;方便管理服务器。 安装服务器默认宝塔面板 使用步骤 到防火墙页面开启8888端口&#xff1a; 点击进入防火墙远程登录服务器。复制面板安全入口查询命令&#xff0c;获取面板安全入口。sudo /etc/init.d/bt default | gr…

快速入门Docker

目录 Docker简介 Dokcer环境配置 Docker HelloWorld运行原理解析 阿里云镜像仓库 常用命令 基本命令 镜像命令 容器命令 Docker简介 Docker 是基于Go语言实现的一个开源项目&#xff0c;通过对应组建的封装&#xff0c;分发&#xff0c;部署&#xff0c;运行等生命周期的管…

如何创建多语言WordPress网站[专家建议]

如果您想有效地接触广泛的国际受众&#xff0c;那么您应该考虑制作一个多语言WordPress网站。您知道吗&#xff0c;61.1% 的网站是英文的&#xff0c;但全球只有 25.9% 的用户实际上可以在线使用这种语言。 多语言功能意味着创建站点的两个或多个语言实例&#xff0c;在大多数…

anaconda安装pytorch

1.需不需要另外创建一个新环境 答案是&#xff1a;可以不需要 所以我的做法是直接在base环境中安装的pytorch 2.python、torch、torchvision版本对应 我的是python3.9&#xff0c;安装的是cuda11.3–torch1.10.1&#xff0c;所以按理来说torchvision为0.11.2 3.离线安装tor…

P4的exercises实现原理

今天介绍一下p4的tutorials-master\utils如何将tutorials-master\exercises下各个小实验的实现&#xff0c;有助于以后自己构建mininet并配置p4交换机&#xff0c;通过本博客可以简单了解&#xff1a; Makefile是如何实现相关的实验的基于p4的mininet如何搭建 1.Makefile干了什…

python-(6-4-3)爬虫---re解析案例

文章目录一 需求二 总体思路1&#xff09;从网址定位到2022必看热片2&#xff09;从2022必看热片定位到子页面的链接地址3&#xff09;请求子页面的链接地址&#xff0c;拿到我们想要的下载地址三 分析步骤1&#xff09;从网址定位到2022必看热片2&#xff09;从2022必看热片定…

开关电源环路稳定性分析(05)-传递函数

大家好&#xff0c;这里是大话硬件。 经过前面4篇文章的梳理&#xff0c;估计很多人已经等不及了&#xff0c;什么时候可以开始环路的分析。为了尽快进入到大家关心的部分&#xff0c;这一讲我们正式进入环路分析的第一部分——传递函数。 传递函数&#xff0c;简单的理解就是…

立体车库管理系统

1、立体车库主界面 左侧为菜单栏中间为监视页面上方为实时报警页面&#xff0c;上方第二页为设备指令&#xff0c;第三页为升降机监测&#xff0c;第三页为穿梭车监测2、立体车库设备状态显示 通用状态显示升降机1#2#和穿梭车1#2#3#的缓存指令编号&#xff0c;点击按钮可以清楚…

【设计模式】32.结构型模式-组合模式(Composite)

一、描述 首先&#xff0c;看一个数据结构&#xff1a; 在平时开发过程中&#xff0c;我们的菜单目录、文件夹目录等都有类似如上的实体结构&#xff0c;其中composite代表父级节点&#xff0c;leaf代表叶子节点&#xff0c;composite可以有子节点&#xff0c;但是leaf下没有…

一文读懂ChatGPT模型原理

&#xff08;本文是ChatGPT原理介绍&#xff0c;但没有任何数学公式&#xff0c;可以放心食用&#xff09; 前言 这两天&#xff0c;ChatGPT模型真可谓称得上是狂拽酷炫D炸天的存在了。一度登上了知乎热搜&#xff0c;这对科技类话题是非常难的存在。不光是做人工智能、机器学习…

ORB-SLAM2 ---- Tracking::TrackWithMotionModel函数

目录 1.函数作用 2.步骤 3.code 4.函数解释 4.1 更新上一帧的位姿&#xff1b;对于双目或RGB-D相机&#xff0c;还会根据深度值生成临时地图点 4.2 根据之前估计的速度&#xff0c;用恒速模型得到当前帧的初始位姿。 4.3 用上一帧地图点进行投影匹配&#xff0c;如果匹…

JDK版本对应其major.minor version,看这一篇就够啦(附java历史版本下载地址)

文章目录前言JDK版本对应其major versionJDK历史版本下载地址前言 今天博主在学习SpringBoot&#xff0c;启动项目时遇到这样一个问题 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.10.1:compile (default-compile) on project springbo…