• C#教程11:类属性


    一、提要

            属性是一种特殊的类成员。我们使用预定义的set和get方法来访问和修改它们。属性读取和写入被转换为获取和设置方法调用。

    二、何为属性

            使用字段表示法(例如object.Name)访问变量比使用自定义方法调用(例如object.GetName)更容易。然而,利用属性,我们仍然具有封装和信息隐藏的优势。换句话说,属性将数据与外部世界隔离,同时具有方便的字段访问。

            接口可以有属性,但不能有字段。

            属性可以是读写(它们同时具有get和set访问器)、只读(它们只有get访问器)或只写(它们只有set访问者)。

    Program.cs

    1. var p = new Person();
    2. p.Name = "Jane";
    3. Console.WriteLine(p.Name);
    4. class Person
    5. {
    6. private string _name;
    7. public string Name
    8. {
    9. get { return _name; }
    10. set { _name = value; }
    11. }
    12. }

            我们有一个具有一个属性的简单Person类。

    var p = new Person();
    p.Name = "Jane";
    
    Console.WriteLine(p.Name);
    

            我们创建Person类的一个实例。我们使用字段符号访问成员字段。

    public string Name
    {
       ...
    }
    

            我们有一个名为Name的属性。它看起来像一个常规方法声明。不同之处在于它具有称为get和set的特定访问器。

    get { return _name; }
    set { _name = value; }
    

            get属性访问器用于返回属性值,set访问器用于分配新值。value关键字用于定义集合索引器分配的值。

    $ dotnet run
    Janes
     

    三、只读属性 read-only properties

            可以创建只读属性。为了创建只读属性,我们省略了set访问器,并在实现中仅提供get访问器。

    Program.cs

    1. var p = new Person();
    2. // p.Name = "Beky";
    3. Console.WriteLine(p.Name);
    4. class Person
    5. {
    6. private string _name = "Jane";
    7. public string Name
    8. {
    9. get { return _name; }
    10. }
    11. }

            在示例中,我们演示了只读属性的使用。

    // p.Name = "Beky";
    

            该行现在已注释。我们不能更改属性。如果我们取消注释该行,C#编译器将发出以下错误:yProgram。cs(4,1):错误CS0200:属性或索引器的人员。无法将名称“”分配给--它是只读的。

    private string _name = "Jane";
    

            我们立即初始化该成员,因为稍后不可能。

    public string Name
    {
        get { return _name; }
    }
    

    我们通过提供get访问器使属性只读。

    四、自动属性 auto-implemented properties

            C#具有自动实现或自动属性。在软件项目中,有许多简单的属性只设置或获取一些简单的值。为了简化编程并缩短代码,创建了自动属性。注意,我们不能在所有情况下使用自动属性;只有简单的。

    Program.cs

    1. var p = new Person();
    2. p.Name = "Jane";
    3. p.Age = 17;
    4. Console.WriteLine($"{p.Name} is {p.Age} years old");
    5. class Person
    6. {
    7. public string Name { get; set; }
    8. public int Age { get; set; }
    9. }

            这个代码要短得多。我们有一个Person类,其中有两个属性:Name和Age。

    var p = new Person();
    p.Name = "Jane";
    p.Age = 17;
    
    Console.WriteLine($"{p.Name} is {p.Age} years old");
    

            我们通常像往常一样使用这些属性。

    public string Name { get; set; }
    public int Age { get; set; }
    

            这里我们有两个自动属性。没有访问器的实现,也没有成员字段。编译器将为我们完成剩下的工作。

    $ dotnet run
    Jane is 17 years old
    

    五、属性体表达式(Expression body definitions)

            自C#7.0以来,属性可以通过表达式体定义简化。表达式体定义由=>符号和要分配给属性或从属性检索的表达式组成。

    Program.cs

    1. var u = new User("John Doe", "gardener");
    2. Console.WriteLine($"{u.Name} is a {u.Occupation}");
    3. class User
    4. {
    5. string name;
    6. string occupation;
    7. public User(string name, string occupation)
    8. {
    9. this.name = name;
    10. this.occupation = occupation;
    11. }
    12. public string Name
    13. {
    14. get => name;
    15. set => name = value;
    16. }
    17. public string Occupation
    18. {
    19. get => occupation;
    20. set => occupation = value;
    21. }
    22. }

            在本例中,我们使用表达式体定义来定义用户类的属性。

    $ dotnet run
    John Doe is a gardenerl

    六、其它注意事项(other notes)

            我们可以使用访问修饰符标记属性,如public、private或protected。属性也可以是静态的、抽象的、虚拟的和密封的。它们的用法与常规方法相同。

    Program.cs

    1. var bs = new Base();
    2. var dr = new Derived();
    3. Console.WriteLine(bs.Name);
    4. Console.WriteLine(dr.Name);
    5. class Base
    6. {
    7. protected string _name = "Base class";
    8. public virtual string Name
    9. {
    10. set { _name = value; }
    11. get { return _name; }
    12. }
    13. }
    14. class Derived : Base
    15. {
    16. protected new string _name = "Derived class";
    17. public override string Name
    18. {
    19. set { _name = value; }
    20. get { return _name; }
    21. }
    22. }

            在前面的示例中,我们定义了一个虚拟属性,并在派生类中重写它。

    public virtual string Name
    {
        set { _name = value; }
        get { return _name; }
    }
    

    名称属性用虚拟关键字标记。

    protected new string _name = "Derived class";
    

            我们在派生类中隐藏了一个成员。为了抑制编译器警告,我们使用new关键字。

    public override string Name
    {
        set { _name = value; }
        get { return _name; }
    }
    

    这里我们重写基类的Name属性。

  • 相关阅读:
    数学建模——统计回归模型
    数字先锋 | 农业农村部大数据公共平台基座上线,天翼云擎起乡村振兴新希望!
    c++ 关于bfs和dfs的相对统一写法
    Android studio在Ubuntu桌面上 创建桌面图标,以及导航栏图标
    网络变压器/网络滤波器(脉冲变压器)选型/定制要明确的要求
    怎样生成分布式的流水ID
    PHP的curl会话
    RK3568 RTL8821cs适配 WPA3连接 与 WPA3热点配置
    MybatisPlus拦截器+注解实现数据权限
    杀不死的Perl
  • 原文地址:https://blog.csdn.net/gongdiwudu/article/details/123445856