cstimothy17-字段,属性,索引器,常量

017 字段、属性、索引器、常量 · 语雀icon-default.png?t=M276https://www.yuque.com/yuejiangliu/dotnet/timothy-csharp-017


程序=数据+算法

字段,属性,索引器,常量都是表示数据的

cstimothy17-字段,属性,索引器,常量_第1张图片

 

C#类型所具有的成员:

字段√

属性√

索引器√

常量√

方法

事件

构造函数

析构函数

运算符

类类型

cstimothy17-字段,属性,索引器,常量_第2张图片

 

字段-成员变量

实例字段-对象

static字段-类

字段初始化的时机

无显式初始化时,字段获得其类型的默认值

值类型-按位归0

引用类型-null

实例字段在对象创建时被加载

static字段在类被加载时,static字段只能被初始化1次,在类被加载时,会调用static构造器,而且static构造器只能被调用1次,所以static初始化可以使用初始化器(=xxx)显式初始化或者在static构造器中初始化

readonly只读字段-为实例/类型保存希望一旦被初始化后就不希望再改变的值

实例只读字段-只有1次机会被赋值-在构造器中,使用带参的构造器

static只读字段-只有1次机会被初始化-在static构造器中

//实例字段和static字段
//readonly字段
using System.Collections.Generic;
namespace cstimothy171
{
    class Program
    {
        static void Main(string[] args)
        {
            List stuList = new List();
            for (int i = 0; i < 100; i++)
            {
                Student stu = new Student(i);
                stu.Age = 24;
                stu.Score = i;
                stuList.Add(stu);
            }
            int totalAge = 0;
            int totalScore = 0;
            foreach (var stu in stuList)
            {
                totalAge += stu.Age;
                totalScore += stu.Score;
            }
            Student.AverageAge = totalAge / Student.Amount;
            Student.AverageScore = totalScore / Student.Amount;
            Student.ReportAmount();
            Student.ReportAverageAge();
            Student.ReportAverageScore();
        }
    }
    class Student
    {
        public readonly int ID;
        public int Age=0;
        public int Score=0;
        
        public static int AverageAge;
        public static int AverageScore;
        public static int Amount;
        public Student(int id)
        {
            Student.Amount++;
            this.ID = id;
        }
        static Student()
        {
            Student.Amount = 0;
            Student.AverageAge = 0;
            Student.AverageScore = 0;
        }
        ~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);
        }
    }
}

cstimothy17-字段,属性,索引器,常量_第3张图片

 

字段由来

字段在cyy已经存在

cyy-cpp-java-c#

cstimothy17-字段,属性,索引器,常量_第4张图片

 cstimothy17-字段,属性,索引器,常量_第5张图片

 

字段声明

特性opt+有效的修饰符组合opt+数据类型type+变量声明器;

有效的修饰符组合

public static int Amount;

public readonly int ID;

public static readonly

变量声明器:

1.变量名

2.变量名+变量的初始化器

变量名=初始值

在声明时显式初始化和在构造器中进行初始化效果相同

cstimothy17-字段,属性,索引器,常量_第6张图片

 

属性-属性是字段的自然扩展

对外-暴露数据,数据可以是存储在字段里的,也可以是动态计算出来的

对内-保护字段不被非法值污染

属性由Get/Set方法对进化而来

字段->属性:

属性由get/set方法对进化而来
//namespace cstimothy172
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            try
//            {
//                Student stu1 = new Student();
//                stu1.SetAge(20);
//                Student stu2 = new Student();
//                stu1.SetAge(20);
//                Student stu3 = new Student();
//                stu1.SetAge(200);
//                int avgAge = (stu1.GetAge() + stu2.GetAge() + stu3.GetAge()) / 3;
//                Console.WriteLine(avgAge);
//            }
//            catch (Exception ex)
//            {
//                Console.WriteLine(ex.Message);
//            }
//        }
//    }
//    class Student
//    {
//        private int age;
//        public int GetAge()
//        {
//            return this.age;
//        }
//        public void SetAge(int value)
//        {
//            if (value >= 0 && value <= 120)
//            {
//                this.age = value;
//            }
//            else
//            {
//                throw new Exception("Age value has error");
//            }
//        }
//    }
//}
namespace cstimothy173
{
    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 = 200;
                int avgAge = (stu1.Age+ stu2.Age+ stu3.Age) / 3;
                Console.WriteLine(avgAge);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
    class Student
    {
        //propfull
        //value是上下文关键字
        private int age;
        public int Age
        {
            get { return age; }
            set
            {
                if (value >= 0 && value <= 120)
                {
                    age = value;
                }
                else
                {
                    throw new Exception("Age value has error");
                }
            }
        }
    }
}

 

属性的声明

完整声明propfull-后台变量和访问器

简略声明prop-只有访问器-不受保护,只为传递数据用

特性opt+有效的修饰符组合+type+属性名{访问器}

public static

只读属性-只有get没有set

属性有get和set,但是set为private,只能在类体内赋值

只写属性-只有set没有get-less

属性是字段的包装器

永远使用属性来暴露数据

字段永远都是private或protected的

委托是方法的包装器

//属性
//实例属性和static属性
namespace cstimothy174
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Student.Amount = -1;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
    class Student
    {
        //实例属性
        private int age;
        public int Age
        {
            get { return age; }
            set
            {
                if (value >= 0 && value <= 120)
                {
                    age = value;
                }
                else
                {
                    throw new Exception("Age value has error");
                }
            }
        }
        //static属性
        private static int amount;
        public static int Amount
        {
            get { return amount; }
            set
            {
                if (value >= 0)
                {
                    amount = value;
                }
                else
                {
                    throw new Exception("Amount must greater than 0");
                }
            }
        }
    }
}
//属性的set为private-只能在类体内赋值
//不同于只读属性-没有set
namespace cstimothy175
{
    class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student();
            stu.SomeMethod(1);
            Console.WriteLine(stu.Age);
        }
    }
    class Student
    {
        private int age;
        public int Age
        {
            get { return age; }
            private set { age = value; }
        }
        public void SomeMethod(int x)
        {
            this.age = x;
        }
    }
}

动态计算值的属性

主动计算

被动计算

//动态计算值的属性-主动计算
//适用于CanWork使用频率低的场景,Age设定频繁的场景
namespace cstimothy176
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Student stu = new Student();
                stu.Age = 12;
                Console.WriteLine(stu.CanWork);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
    class Student
    {
        private int age;
        public int Age
        {
            get { return age; }
            set { age = value; }
        }
        //CanWork属性并没有封装字段
        //它的值是实时动态计算出来的
        public bool CanWork
        {
            get
            {
                if (this.age >= 16)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
    }
}
//动态计算值的属性-被动计算
//适用于canWork使用频繁的场景,每次设定Age时就计算canWork
namespace cstimothy177
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Student stu = new Student();
                stu.Age = 12;
                Console.WriteLine(stu.CanWork);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
    class Student
    {
        private int age;
        public int Age
        {
            get { return age; }
            set
            {
                age = value;
                this.CalculateCanWork();
            }
        }
        //只读属性
        private bool canWork;
        public bool CanWork
        {
            get { return canWork; }
        }
        private void CalculateCanWork()
        {
            if (this.age >= 16)
            {
                this.canWork = true;
            }
            else
            {
                this.canWork = false;
            }
        }
    }
}

cstimothy17-字段,属性,索引器,常量_第7张图片

 

索引器能够使对象能够能下标进行访问

一般拥有索引器的都是集合类型

此时example为讲解方便,使用非集合类型

声明索引器-indexer tab*2

//索引器
using System.Collections.Generic;
namespace cstimothy178
{
    class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student();
            var mathScore = stu["Math"];
            Console.WriteLine(mathScore==null);
            stu["Math"] = 90;
            stu["Math"] = 100;
            mathScore = stu["Math"];
            Console.WriteLine(mathScore);
        }
    }
    class Student
    {
        //私有字段
        private Dictionary dict = new Dictionary();
        //index tab*2
        //此处返回值为int?-可空的int类型
        public int? this[string subject]
        {
            get
            {
                if (this.dict.ContainsKey(subject))
                {
                    return this.dict[subject];
                }
                else
                {
                    return null;
                }
            }
            set
            {
                //因为返回值为可空类型,所以上来先判断
                if (value.HasValue == false)
                {
                    throw new Exception("score cannot be null");
                }
                if (this.dict.ContainsKey(subject))
                {
                    this.dict[subject] = value.Value;
                }
                else
                {
                    this.dict.Add(subject, value.Value);
                }
            }
        }
    }
}

cstimothy17-字段,属性,索引器,常量_第8张图片

 

常量

Math.PI

public const double PI=3.14159

int.MaxValue

public const int MaxValue

int.MinValue

public const int MinValue

常量隶属于类型而不是对象,没有实例常量

类型.常量

实例常量由只读实例字段来担当-只有1次机会初始化,在声明的时候,初始化器初始化or在构造器中初始化

成员常量和局部常量

成员常量

Math.PI

public const string WebsiteURL= "xxx";

局部常量-在方法体中-const int x=100;

只读的应用场景

1.常量-在编译器的时候会用常量的值代替常量标识符

成员常量

局部常量

2.只读字段-没有实例常量,为了防止对象的某个值被修改则使用只读字段

3.只读属性-向外暴露不允许修改的数据

对象-实例只读属性

类型-static只读属性-只有get没有set-区别与set为private的属性

4.静态只读字段

常量的数据类型只能是基本数据类型

不能用类类型作为常量的类型-此时使用静态只读字段-static readonly

//常量
namespace cstimothy179
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Student.WebsiteURL);
        }
    }
    class Student
    {
        //成员常量
        public const string WebsiteURL= "xxx";
        //静态只读字段
        public static readonly Building Location = new Building("some address");
    }
    class Building
    {
        public string Address { get; set; }
        public Building(string address)
        {
            this.Address = address;
        }
    }
}

cstimothy17-字段,属性,索引器,常量_第9张图片

 

你可能感兴趣的:(c#)