zoukankan      html  css  js  c++  java
  • 第10章 属性

    属性允许源代码用一个简化的语法来调用一个方法。

    CLR支持两种属性:无参属性 (parameterless property) ,有参属性(parameterful property)

    C#中将有参属性称为索引器(indexer)

    10.1无参属性

    一般用类型的字段成员来实现获取或改变类型的状态信息。

    面向对象设计和编程的重要原则之一就是数据封装(data encapsulation),它意味着类型的字段永远不应该公开。强烈建议将所有的字段都设为private。

    要允许获取类型状态信息,就公开一个针对该用途的方法。

    封装了字段访问的方法通常称为访问器(accessor)方法(如下面的GetName,SetName)。访问器方法可以对数据的合理性进行检查,确保对象的状态不被破坏。

    public sealed class Employee

        {

            private String m_Nmae;

            private Int32 m_Age;

            public String GetName()

            {

                return m_Nmae;

            }

            public void SetName(String value)

            {

                m_Nmae = value;

            }

            public Int32 GetAge()

            {

                return m_Age;

            }

            public void SetAge(Int32 value)

            {

                if (value < 0)

                {

                    throw new ArgumentOutOfRangeException("value", value.ToString(), "The value must be grater than or equal to 0");

                }

                m_Age = value;

            }

     public static void Main()

            {

                Employee e = new Employee();

                e.SetName("Jeffery Richter");

                String EmployeeName = e.GetName();

                e.SetAge(41);

                e.SetAge(-5);

                Int32 EmployeeAge = e.GetAge();

            }

        }

    将SetXxx方法标记为protected,就可以实现只允许派生类型修改值。

    以上代码中,类型的用户必须调用方法,而不能直接引用一个字段名。

    编程语言和CLR还提供了一种称为属性(property)的机制,如下:

    public sealed class Employee

        {

            private String m_Nmae;

            private Int32 m_Age;

            public String Name

            {

                get { return (m_Nmae); }

                set { m_Nmae = value; }

            }

            public Int32 Age

            {

                get { return (m_Age); }

                set

                {

                    if (value < 0)

                    {

                        throw new ArgumentOutOfRangeException("value", value.ToString(), "The value must be greater than or equal to 0");

                    }

                    m_Age = value;

                }

            }

            public static void Main()

            {

                Employee e = new Employee();

                e.Name = "Jeffery Richter";

                String EmployeeName = e.Name;

                e.Age = 41;

                e.Age = -5;

                Int32 EmployeeAge = e.Age;

            }

        }

    可将属性想象成智能字段(smart field),即背后有额外逻辑的字段。

    每个属性都有一个名称(Name,Age)和一个类型(String,Int32不能为void)。属性不能重载。定义属性时,可以省略set方法来定义一个只读属性,或者省略get方法来定义一个只写属性。

    通过属性的get和set方法来操作类型内私有的字段,是一种很常见的做法。

    以前面的Employee类型为例。编译器编译这个类型时,会发现其中的Name和Age属性。由于两个属性都有get和set访问器方法,所以编译器在Employee类型中生成4个方法定义。

    10.1.1自动实现的属性

    如果只是为了封装一个支持字段而创建一个属性,C#还提供了更简单的语法,称为自动实现的属性(automatically Implemented Property)。

    10.1.2合理定义属性

    我个人不喜欢属性

    10.1.3对象和集合初始化器

    System.Collections命名空间包含可使用的集合类和相关的接口,提供了集合的基本功能。  

    IEnumerable 接口

    System.Collections

    该枚举数支持在非泛型集合上进行简单迭代

    所有继承了IEnumerable的类,要使用foreach迭代器时,就需要使用该方法。因此也只有实现了该接口的类才可以使用foreach。

    名称

    说明

    GetEnumerator()

    返回循环访问集合的枚举数。

    IList 接口

    System.Collections

    IList 是 ICollection 接口的子代,并且是所有(非???)泛型列表的基接口

    IList继承自ICollection

    名称

    说明

    Add(Object)

    将某项添加到 IList 中。

    Clear()

    从 IList 中移除所有项。

    Contains(Object)

    确定 IList 是否包含特定值。

    CopyTo(Array, Int32)

    从特定的 Array 索引处开始,将 ICollection 的元素复制到一个 Array 中。(从 ICollection 继承。)

    GetEnumerator()

    返回循环访问集合的枚举数。(从 IEnumerable 继承。)

    IndexOf(Object)

    确定 IList 中特定项的索引。

    Insert(Int32, Object)

    将一个项插入指定索引处的 IList。

    Remove(Object)

    从 IList 中移除特定对象的第一个匹配项。

    RemoveAt(Int32)

    移除指定索引处的 IList 项。

    ICollection<T> 接口

    System.Collections.Generic

    定义操作泛型集合的方法。

    ICollection继承自IEnumerable

    名称

    说明

    Add(T)

    将某项添加到 ICollection<T> 中。

    Clear()

    从 ICollection<T> 中移除所有项。

    Contains(T)

    确定 ICollection<T> 是否包含特定值。

    CopyTo(T[], Int32)

    从特定的 Array 索引开始,将 ICollection<T> 的元素复制到一个 Array 中。

    GetEnumerator()

    返回一个循环访问集合的枚举器。(从 IEnumerable<T> 继承。)

    Remove(T)

    从 ICollection<T> 中移除特定对象的第一个匹配项。

    ICollection主要针对静态集合;IList主要针对动态集合。

    如果一个方法的返回值是IEnumerable<T> ,必须在方法后面使用.ToList()方法才能得到一个集合数据。

    集合的初始化被认为是相加(Additive)操作,而非替换的操作。编译器发现Student属性的类型是List<String>,而且这个类型实现了IEnumerable<String>接口。如下:

    public sealed class Classroom

    {

        private List<String> m_students = new List<String>();

        public List<String> Students { get { return m_students; } }

        public Classroom() { }

        public static void Main()

        {

            Classroom classroom = new Classroom

            {

                Students = { "Chris","Jeff" }

            };

            //Classroom classroom = new Classroom();

            //classroom.Students.Add("Chris");

            //classroom.Students.Add("Jeff");

            foreach (var student in classroom.Students)

                Console.WriteLine(student);

        }

    }

    10.1.4 匿名类型

    10.1.5 System.Tuple类型

    10.2 有参属性

    重看

  • 相关阅读:
    括号配对问题 (栈的应用)
    poj 1363 火车进站 (栈的应用)
    算法训练题
    进制-Adding Two Negabinary Numbers
    翻转-Flip Columns For Maximum Number of Equal Rows
    图论-完全二叉树判定-Check Completeness of a Binary Tree
    动态规划-Maximum Subarray-Maximum Sum Circular Subarray
    贪心-最大相容区间-Maximum Number of Events That Can Be Attended
    动态规划-LCS-Uncrossed Lines
    数学-绝对值-Reverse Subarray To Maximize Array Value
  • 原文地址:https://www.cnblogs.com/chrisghb8812/p/5618292.html
Copyright © 2011-2022 走看看