ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C#学习(8)字段,属性,索引器,常量

2020-02-22 18:03:05  阅读:291  来源: 互联网

标签:常量 stu C# class 索引 int static Student public


C#的所有类型

 C#的所有类型

字段

  • 什么是字段
    • 字段(field)是一种表示与对象或类型(类与结构体)关联的变量
    • 字段是类型的成员,旧称“成员变量”
    • 与对象关联的字段亦称“实例字段”
    • 与类型关联的字段称为“静态字段”,由static修饰
namespace Field
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> stulist = new List<Student>();
            for (int i = 0; i < 100; i++)
            {
                Student stu = new Student();
                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 int Age;
        public int Score;

        public static int AverageAge;
        public static int AverageScore;
        public static int Amount;

        public 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#语言定义文档
    • 尽管字段声明带有分号,但它不是语句
    • 字段的名字一定是名词
      在这里插入图片描述
  • 字段的初始值
    • 无显式初始化时,字段获得其类型的默认值,所以字段“永远都不会未被初始化”
    • 实例字段初始化的时机——对象创建时
    • 静态字段初始化的时机——类型被加载时
  • 只读字段
    • 实例只读字段
namespace Field
{
    class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student(1);
            Console.WriteLine(stu.ID);

            stu.ID = 2;//(无法通过编译)只读字段无法通过赋值修改
        }
    }

    class Student
    {
        public readonly int ID;
        public Student(int id)
        {
            this.ID = id;//只读字段只能在构造器中修改默认值
        }
    }
 
}
  • 静态只读字段
namespace Field
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Brush.defaultColor.Red);
            Console.WriteLine(Brush.defaultColor.Green);
            Console.WriteLine(Brush.defaultColor.Blue);

            Brush.defaultColor = new Color() { Red = 255, Green = 255, Blue = 255 };//(无法通过编译)静态只读字段同样也不能赋值修改
        }

        
    }

    struct Color
    {
        public int Red;
        public int Green;
        public int Blue;
    }

    class Brush
    {
        public static readonly Color defaultColor;
        static Brush()
        {
           Brush.defaultColor = new Color() { Red = 0, Green = 0, Blue = 0 };
        }
    }
 
}

属性

  • 什么是属性
    • 属性(Property)是一种用于访问对象或类型的特征的成员,特征反映了状态
    • 属性是字段的自然扩展
      • 从命名上看,字段(field)更偏向于实例对象再内存中的布局,属性(property)更偏向于反映现实世界对象的特征
      • 对外:暴露数据,数据可以是存储在字段里的,也可以是动态计算出来的
      • 对内:保护字段不被非法值“污染”
    • 属性由Get/Set方法对进化而来
namespace Property
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Student stu1 = new Student();
                stu1.Age = 20;
                //stu1.SetAge(10);
                Student stu2 = new Student();
                stu2.Age = 20;
                //stu2.SetAge(10);
                Student stu3 = new Student();
                stu3.Age = 20;
                //stu3.SetAge(10);

                int avgAge = (stu1.Age + stu2.Age + stu3.Age) / 3;
                //int avg = (stu1.GetAge() + stu2.GetAge() + stu3.GetAge());  C中的Get() set()方法对
                Console.WriteLine(avgAge);

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        
    }

    class Student
    {
        private int age;
        public int Age//声明了一个Age属性
        {
            get
            {
                return this.age;
            }
            set
            {
                if (value>=0&&value<=120)        
                {
                    this.age = value;
                }
                else
                {
                    throw new Exception("Age has Error");
                }
            }
        }

        public int GetAge()
        {
            return this.age;
        }

        public void SetAge(int value)
        {
            if (value >= 0 && value <= 120)
            {
                this.age = value;
            }
            else
            {
                throw new Exception("Age has Error");
            }
        }

    }
}


  • 又一个“语法糖”——属性背后的秘密
  • 属性的声明
    • 完整声明(快捷键propfull双击tab)——后台(back)成员变量与访问器
namespace Property
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Student stu = new Student();
                stu.Age = 20;
                Student.Amount = 100;
            }
            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");
                }
            }
        }

        private static int amount;

        public static int Amount//静态属性
        {
            get { return amount; }
            set
            {
                if (value > 0)
                {
                    amount = value;
                }
                else
                {
                    throw new Exception("Amount value has error");
                }
            }
        }
    }  
}

  • 简略声明(快捷键prop双击tab)——只有访问器(查看IL代码)
namespace Property
{
    class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student();
            stu.Age = 1;
        }

        
    }

    class Student
    {
        public int Age { get; set; }
    }  
}
  • 动态计算值的属性
namespace Property
{
    class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student();
            stu.Age = 18;
            Console.WriteLine(stu.canWork);
        }

        
    }

    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;
                }
            }
        }
    }  
}

另一种写法:

namespace Property
{
    class Program
    {
        static void Main(string[] args)
        {

         
        }
    
    }

    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;
            }
        }


    }
  
}

  • 注意实例属性和静态属性

  • 属性的名字——定是名词

  • 只读属性——只有Getter,没有Setter。(尽管语法上正确,几乎没有人使用“只写属性”,因为属性的主要目的是通过向外暴露数据而表示对象/类型的状态)

  • 属性与字段的关系

  • 一般情况下,它们都用于表示实体(对象或类型)的状态

  • 属性大多数情况下是字段的包装器(warpper)

  • 建议:永远使用属性(而不是字段)来暴露数据,即字段永远都是private或propected的

索引器

  • 什么是索引器
    • 索引器(indexer)是这样一种成员:它使对象能够用与数组相同的方式(即使用下标)进行索引
  • 索引器的声明(键入indexer双击tab)
    • 参见C#语言定义文档
    • 注意:没有静态索引器
namespace Property
{
    class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student();
            stu["math"] = 90;
            var mathScore = stu["math"];
            Console.WriteLine(mathScore);
        }
    
    }

    class Student
    {
        private Dictionary<string, int> scoreDictionary = new Dictionary<string, int>();

        public int? this[string subject]//声明索引器
        {
            get
            {
                if (this.scoreDictionary.ContainsKey(subject))
                {
                    return this.scoreDictionary[subject];
                }
                else
                {
                    return null;
                }
            }
            set
            {
                if (value.HasValue == false)
                {
                    throw new Exception("Score value has error");
                }
                if (this.scoreDictionary.ContainsKey(subject))
                {
                    this.scoreDictionary[subject] = value.Value;
                }
                else
                {
                    this.scoreDictionary.Add(subject, value.Value);
                }
            }
        }
    }
  
}

常量

  • 什么是常量
    • 常量(constant)是表示常量值(即,可以在编译时计算的值)的类成员
    • 常量隶属于类型而不是对象,即没有“实例常量”。(“实例常量”的角色由只读实例字段来担当)
    • 注意区分成员常量与局部常量
  • 常量的声明
namespace Property
{
   class Program
   {
       static void Main(string[] args)
       {
           Console.WriteLine(Web.website);
       }
   
   }

   class Web
   {
       public const string website = "http://www.bilibili.com";//声明常量
   }
}
  • 各种“只读”的应用场景
    • 为了提高程序可读性和执行效率——常量
    • 为了防止对象的值被修改——只读字段
    • 向外暴露不允许修改的数据——只读属性(静态或非静态),功能与常量有一些重叠
    • 当希望成为常量的值其类型不能被常量声明接受时(类/自定义结构体)——静态只读字段
WWWWWangXO 发布了8 篇原创文章 · 获赞 0 · 访问量 43 私信 关注

标签:常量,stu,C#,class,索引,int,static,Student,public
来源: https://blog.csdn.net/WWWWWangXO/article/details/104441288

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有