• 【C#语言入门】14. 字段,属性,索引器,常量


    【C#语言入门】14. 字段,属性,索引器,常量

    一、字段

    • 什么是字段
      • 字段(field)是一种表示与对象或者类型(类与结构体)关联的变量
      • 字段是类型的成员,旧称“成员变量”
      • 与对象关联的字段亦称“实例字段”
      • 与类型关联的字段称为“静态字段”,由static修饰
    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 字段的声明

      • 字段是类型的成员,所以要写在类体里面,而不是在函数体里面。
      • attributesopt field-modifiersopt type variable-declaratiors ;
      • 只读(readonly)字段可以接受初始化,但不能修改。
      • 尽管字段声明带有分号,但是它不是语句,语句存在于方法体中。
      • 字段的名字一定是名词。
    • 字段的初始值

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

      • 实例只读字段(直接写后面,或者实例构造器)
      • 静态只读字段(直接写后面,或者静态构造器)

    二、属性

    • 什么是属性
      • 属性(property)是一种用于访问对象或者类型的特征的成员,特征反应了状态。
      • 属性是字段的自然扩展
        • 从命名上看,field更偏向于实例对象在内存中的布局,property更偏向于反映现实世界对象的特征
        • 对外:暴露数据,数据可以是存储在字段里面的,也可以是动态计算表出来的
        • 对内:保护字段不被非法值“污染”
      • 属性由Get/Set方法对进化而来
      • 又一个“语法糖”——属性背后的秘密(语法糖是指用简单的表示复杂的逻辑)
    class Program
    {
        static void Main(string[] args)
        {
            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);
        }
    }
    
    
    class Student
    {
        private int age;
        
        public int GetAge()
        {
           return int this.age;
        }
        
        public void SetAge(int value)
        {
            if(value>0 && value<=120)
            {
                this.age = value;
            }
            else
            {
                throw new Exception("Age value has error.");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    属性↓

    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;
        
        public int Age
        {
           get
           {
               return this.age;
           }
           
           set
           {
               if(value>0 && value<=120)
               {
                   this.age = value;
               }
               else
               {
                   throw new Exception("Age value has error.");
               }   
           }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 属性的声明

      • 完整声明——后台(back)成员变量与访问器(注意使用code snippet和refactor工具)(propfull+双回车)
      • attributesopt field-modifiersopt type member-name { accessor-declarations }
      • 简略声明——只有访问器(prop+双回车)
      • 动态计算值的属性
      • 注意实例属性和静态属性
      • 属性的名字一定是名词
      • 只读属性——只有getter没有setter
      • 尽管语法上正确,但几乎没有人使用“只写属性”,因为属性的主要目的是通过向外暴露数据而表示对象/类型的状态
    • 属性与字段的关系

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

    三、索引器(概述)

    • 什么是索引器
      • 索引器(indexer)是这样一种成员:它使对象能够用于数组相同的方式(即使用下标)进行索引(indexer+双回车)
    class Student
    {
        private Dictionary<string, int> scoreDictionary = new Dictionary<string, int>();
        
        public int? this[string subject]
        {
            get
            {
                if(this.scoreDictionary.ContainKey(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;
                }
                else
                {
                    this.scoreDictionary.Add(subject, value.Value);
                }
            }
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    四、常量

    • 什么是常量

      • 常量(cosntant)是表示常量值(即,可以在编译时计算的值)的类成员。
      • 常量隶属于类型而不是对象,即没有“实例常量”。但是可以用只读实例字段充当“实例常量”
      • 注意区分成员常量和局部常量。
    • 常量的声明

    • 各种“只读”的应用场景

      • 为了提高程序可读性和执行效率——常量
      • 为了防止对象的值被改变——只读字段
      • 向外暴露不允许修改的数据——只读属性(静态或非静态),功能与常量有一些重叠
      • 当希望成为常量的值其类型不能被常量声明接受时(类/自定义结构体)——静态只读字段
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(WASPEC.WebsiteURL);
        }
    }
    
    class WASPEC
    {
        public const string WebsiteURL = "http://www.waspec.org";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    [附源码]java毕业设计吾家具线上销售管理系统
    【智能优化算法 】基于适应度相关优化器求解单目标优化问题附matlab代码
    779. 第K个语法符号
    if-else:if判断语句和执行语句之间相差1个时钟周期吗?并行执行吗?有优先级吗?
    AMQP协议详解
    算法刷题笔记 食物链(详细注释的C++实现)
    微擎模块 智能AI雷达名片小程序1.6.1原版,更新商城可以不显示价格
    同态加密:分圆多项式简介
    什么是云原生的应用?
    【python练习】羊车门问题
  • 原文地址:https://blog.csdn.net/Cziii/article/details/136476130