开放的编程资料库

当前位置:我爱分享网 > C#教程 > 正文

C# 属性

C#属性教程展示了如何在C#中使用属性。

属性是一个成员,它提供了一种灵活的机制来读取、写入或计算私有字段的值。

属性使用访问器,通过访问器可以读取、写入或操作私有字段的值。属性读取和写入被转换为get和set方法调用。属性保护数据不受外界影响,同时具有方便的现场访问。

get属性访问器用于返回属性值,set属性访问器用于分配新值。init属性访问器仅在对象构造期间用于分配新值。value关键字用于定义由setinit访问器分配的值。

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

带有支持字段的C#属性

以下示例使用带有支持字段的属性。

var u = new User();
u.Name = "Jane";

Console.WriteLine(u.Name);

class User
{
    private string _name;

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

我们有Name属性和_namebackingfield。

var u = new User();
u.Name = "Jane";
    
Console.WriteLine(u.Name);

我们创建了一个User类的实例。我们使用字段表示法访问成员字段。

public string Name
{
   ...
}

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

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

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

C#只读属性

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

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

class User
{
    private string _name;
    private string _occupation;

    public User(string name, string occupation)
    {
        _name = name;
        _occupation = occupation;
    }

    public string Name
    {
        get { return _name; }
    }

    public string Occupation
    {
        get { return _occupation; }
    }

    public override string ToString()
    {
        return $"{_name} is a {_occupation}";
    }
}

在示例中,我们有只读属性。一旦在构造函数中初始化,它们就不能被修改。

public string Name
{
    get { return _name; }
}

我们通过提供一个get访问器将属性设置为只读。

C#自动实现的属性

C#具有自动实现或自动属性。借助自动属性,编译器可以透明地为我们提供支持字段。

var u = new User();
u.Name = "John Doe";
u.Occupation = "gardener";

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

class User
{
    public string Name { get; set; }
    public string Occupation { get; set; }
}

这段代码要短得多。我们有一个User类,其中有两个属性:NameOccupation

var u = new User();
u.Name = "John Doe";
u.Occupation = "gardener";
    
Console.WriteLine($"{u.Name} is a {u.Occupation}");

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

public string Name { get; set; }
public string Occupation { get; set; }

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

$ dotnet run
John Doe is a gardener

C#初始化属性

init关键字用于创建仅初始化属性;这些属性只能在对象构造期间初始化。

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

class User
{
    public User(string name, string occupation)
    {
        Name = name;
        Occupation = occupation;
    }

    public string Name { get; init; }
    public string Occupation { get; init; }

    public override string ToString()
    {
        return $"{Name} is a {Occupation}";
    }
}

我们定义了两个init-only属性;它们在构造函数中初始化。之后,它们变得不可变。

public string Name { get; init; }
public string Occupation { get; init; }

init-only属性是使用init关键字创建的。

C#表达式主体定义

可以使用表达式主体定义来简化属性。表达式主体定义由=>符号和后跟要分配给属性或从属性检索的表达式组成。

var u = new User("John Doe", "gardener");
Console.WriteLine($"{u.Name} is a {u.Occupation}");

class User
{
    private string _name;
    private string _occupation;

    public User(string name, string occupation)
    {
        Name = name;
        Occupation = occupation;
    }

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

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

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

$ dotnet run
John Doe is a gardener

其他说明

我们可以使用访问修饰符标记属性,例如publicprivateprotected。属性也可以是staticabstractvirtualsealed。它们的用法与常规方法相同。

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

在前面的示例中,我们定义了一个虚拟属性并在Derived类中覆盖它。

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

Name属性用virtual关键字标记。

protected new string _name = "Derived class";

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

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

在这里我们覆盖了Base类的Name属性。

在本文中,我们介绍了C#属性。

列出所有C#教程。

未经允许不得转载:我爱分享网 » C# 属性

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏