(二)CSharp-字段-属性-常量

本文介绍了C#中字段、属性和常量的概念与用法。字段是类型或对象的变量,属性作为字段的包装器提供数据访问控制,常量则是在编译时确定的不可变值。属性由get和set访问器组成,可实现数据验证和计算逻辑。建议使用属性而非字段公开数据。同时,文章讨论了只读字段和常量的差异,以及静态属性和readonly修饰符的应用场景。
摘要由CSDN通过智能技术生成

一、字段

什么是字段

  • 字段(filed)是一种表示与对象或类型(类或结构体)关联的变量
  • 字段是类型的成员,旧称“成员变量”
  • 与对象关联的字段亦称“实例字段”
  • 与类型关联的字段称为“静态字段”,由 static 修饰

字段的声明

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

字段的初始值

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

只读字段

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

二、属性

1、什么是属性

  • 【1】属性(property)是一种用于访问对象或类型的特征的成员,特征反映了状态
  • 【2】属性是字段的自然扩展
    • 1)从命名上看,field 更偏向于实例对象在内存中的布局,property 更偏向于反映现实世界对象的特征
    • 2)对外: 暴露数据,数据可以是存储在字段里的,也可以是动态计算出来的
    • 3)对内: 保护字段不被非法值“污染”
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Student stu1 = new Student();
                stu1.Age = 20;
                Student stu2 = new Student();
                stu2.Age = 200;
                int avgAge = (stu1.Age + stu2.Age) / 2;
                Console.WriteLine(avgAge);
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
          
        }
    }

    class Student
    {
        private int age;

        public int Age
        {
            get { return age; }
            set
            {
                if (value > 0 && value <= 120)
                {
                    this.age = value;
                }
                else
                {
                    throw new Exception("Age value has error.");
                }
            }
        }

    }
}

  • 【3】属性由 Get/Set 方法对进化而来
  • 【4】又一个“语法糖”——属性背后的秘密

2、属性的声明

  • 完整声明——后台(back)成员变量与访问器(注意使用 code snippet 和 refactor 工具)
    (输入 propfull,按两下Tab,生成如下代码,便是完整声明)
 private int myVar;

        public int MyProperty
        {
            get { return myVar; }
            set { myVar = value; }
        }
  • 简略声明——只有访问器(查看 IL 代码)
   public int MyProperty { get; set; }
  • 动态计算值的属性
 class Student
    {

        private int age;

        public int Age
        {
            get { return age; }
            set { age = value; }
        }

        public bool CanWork
        {
            get
            {
                if(this.age >= 16)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

    }
  • 注意实例属性和静态属性
  • 属性的名字一定是名词
  • 只读属性——只有 getter 没有 setter
    • 尽管语法上正确,几乎没有人使用“只写属性”,因为属性的主要目的是通过向外暴露数据而表示对象/类型的状态

3、属性与字段的关系

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

三、常量

1、常量的声明和定义

什么是常量

  • 常量(constant)是表示常量值(即,可以在编译时计算的值)的类成员
  • 常量隶属于类型而不是对象,即没有“实例常量”
  • 注意区分成员常量与局部常量

常量的声明
1、各种“只读”的应用场景

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

2、和字段不同,属性是一个函数成员。

  • 它不一定为数据存储分配内存。
  • 它执行代码。

3、属性是一组(两个)匹配的、命名的、称为访问器的方法。

  • set 访问器为属性赋值。(有 value 参数和返回类型 void)
  • get 访问器从属性获取值。(返回类型 void)
  • 属性本身没有任何存储。访问器决定如何处理发送进来的数据,以及将什么数据发送出去。
    方法签名

由方法的名称和形参列表组成。具体来说,一个方法的签名由它的名称以及它的形参的个数、修饰符和类型组成。

只读和只写属性
要想不定义属性的某个访问器

  • 只有 get 访问器的属性称为只读属性。
  • 只有 set 访问器的属性称为只写属性。
  • 两个访问器中至少有一个必须定义,否则编译器会产生一条错误消息。

自动属性

请添加图片描述

静态属性

属性可以声明为 static。静态属性的访问器和所有静态成员一样,具有以下特点。

  • 不能访问类的实例成员,但能被实例成员访问。
  • 不管类是否有实例,它们都是存在的。
  • 在类的内部,可以仅使用名称来引用静态属性。
  • 在类的外部,可以通过类名或者使用 using static 结构来引用静态属性。

请添加图片描述

2、readonly 修饰符

const与readonly 的区别

  • const 字段只能在字段的声明语句中初始化,而 readonly 字段可以在下列任意位置设置它的值
    • 字段声明语句,类似于 const。
    • 类的任何构造函数、如果是 static 字段,初始化必须在静态构造函数中完成。
  • const 字段的值必须可在编译时决定,而 readonly 字段的值可以在运行时决定。这种自由性允许你在不同的环境或不同的构造函数中设置不同的值。
  • const 的行为总是静态的,而对于 readonly 字段以下两点是正确的。
    • 它可以是实例字段,也可以是静态字段。
    • 它在内存中有存储位置。

跟const 区别的用处-例子:

 class Shape
    {
        readonly double PI = 3.1416;
        readonly int NumberOfSides;
        public Shape(double side1,double side2)
        {
            NumberOfSides = 4;
        }

        public Shape(double side1,double side2,double side3)
        {
            NumberOfSides = 3;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值