【C#教程11/16】:类属性

一、提要

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

二、何为属性

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

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

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

Program.cs

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

Console.WriteLine(p.Name);

class Person
{
    private string _name;

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

        我们有一个具有一个属性的简单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

var p = new Person();
// p.Name = "Beky";

Console.WriteLine(p.Name);

class Person
{
    private string _name = "Jane";

    public string Name
    {
        get { return _name; }
    }
}

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

// 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

var p = new Person();
p.Name = "Jane";
p.Age = 17;

Console.WriteLine($"{p.Name} is {p.Age} years old");

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

        这个代码要短得多。我们有一个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

var u = new User("John Doe", "gardener");

Console.WriteLine($"{u.Name} is a {u.Occupation}");

class User
{
    string name;
    string occupation;

    public User(string name, string occupation)
    {
        this.name = name;
        this.occupation = occupation;
    }

    public string Name
    {
        get => name;
        set => name = value;
    }

    public string Occupation
    {
        get => occupation;
        set => occupation = value;
    }
}

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

$ dotnet run
John Doe is a gardenerl

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

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

Program.cs

var bs = new Base();
var dr = new Derived();

Console.WriteLine(bs.Name);
Console.WriteLine(dr.Name);
       
class Base
{
    protected string _name = "Base class";

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

class Derived : Base
{
    protected new string _name = "Derived class";

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

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

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属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无水先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值