【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);
    }
}
  • 字段的声明

    • 字段是类型的成员,所以要写在类体里面,而不是在函数体里面。
    • 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.");
        }
    }
}

属性↓

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.");
           }   
       }
    }
}
  • 属性的声明

    • 完整声明——后台(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);
            }
        }
    }

}

四、常量

  • 什么是常量

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

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

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

class WASPEC
{
    public const string WebsiteURL = "http://www.waspec.org";
}
  • 38
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值