C#中的属性

简介: C#中的属性

简介

属性是代表类的实例或类中的一个数据项的成员,使用属性看起来非常像写入或读取一个字段,语法是相同的。

下面的代码展示了名称为D的类的使用,它有一个公有字段和一个公有属性,从用法无法区分它们。

D d = new D();
d.MyField = 7; //给字段赋值
d.MyProperty = 10; //给属性赋值
Console.WriteLine($"{d.MyField} {d.MyProperty}"); //读取字段和属性


与字段类似,属性有如下特征:

1、它是命名的类成员。

2、它有类型。

3、它可以被赋值和读取。

和字段不同的是,属性是一个函数成员。

1、它不为数据存储分配内存。

2、它执行代码。

一个关于属性的简单示例

代码如下:

public class Person
{
    private string name; // 私有字段
    public string Name
    {
        get
        {
            // 这是属性的get访问器,用于获取属性的值
            return name;
        }
        set
        {
            // 这是属性的set访问器,用于设置属性的值
            name = value;
        }
    }
}


这个示例的图示如下:

在这个示例中,Name 属性提供了对 name 字段的访问,但它本身并不存储数据。当您使用 person.Name 读取属性时,实际上调用了属性的get访问器来获取字段的值,而当您使用 person.Name = "John" 设置属性时,实际上调用了属性的set访问器来设置字段的值。

属性声明和访问器

set和get访问器有预定义的语法和语义。可以把set访问器想象成一个方法,带有单一的参数“设置”属性的值,get访问器没有参数并从属性返回一个值。

set访问器的特点

1、有一个单独的、隐式的值参,名称为value,与属性的类型相同。

2、返回类型void。

get访问器的特点

1、没有参数。

2、返回类型与属性类型相同。

属性和关联字段

属性常和字段关联,一种常见的方式是在类中将字段声明为private以封装该字段,并声明一个public属性来控制从类的外部对该字段的访问,和属性关联的字段常被称为后备字段或后备存储。

属性和它们的后备字段有几种命名约定。

一种约定是两个名称使用相同的内容,但字段使用Camel大小写,属性使用Pascal大小写。(Camel大小写风格中,复合词标识符中每个单词的首字母大写,出来第一个单词,其余字母都是小写,Pascal大小写风格中,复合词中每个单词的首字母都是大写。)

另一种约定是属性使用Pascal大小写,字段使用相同标识符的Camel大小写版本,并以下划线开始。

两种约定的示例代码如下:

// 第一种约定的写法
        private int firstField; // Camel大小写
        public int FirstField   // Pascal大小写
        {
            get { return firstField; }
            set { firstField = value;}
        }
        // 第二种约定的写法
        private int _secondField; // 下划线及Camel大小写
        public int SecondField   // Pascal大小写
        {
            get { return _secondField; }
            set { _secondField = value; }
        }

   

只读和只写属性

要想不定义属性的某个访问器,可以忽略该访问器的声明。

只有get访问器的属性称为只读属性。只读属性是一种安全的,把一项数据从类或类的实例中传出,而不允许太多访问方法。

只有set访问器的属性称为只写属性。只写属性是一种安全的,把一项数据从类的外部传入类,而不允许太多的访问的方法。

两个访问器至少有一个必须定义,否则编译器会报错,如下图所示:

自动实现属性

因为属性经常被关联到后备字段,C#提供了自动实现属性(automatically implemented property),允许只声明属性而不声明后备字段,编译器会为我们创建隐藏的后备字段,并且自动挂接到get和set访问器上。

自动实现属性的注意点:

1、不声明后备字段,编译器会根据属性的类型分配存储。

2、不能提供访问器的方法体,它们必须被简单地声明为分号。get担当简单的内存读,set担当简单的写。

3、只有通过访问器才能访问后备字段。因为不能用其他的方法访问它,所以实现只读和只写属性没有意义,因此必须同时提供读写访问器。

一个自动实现属性的示例,代码如下:

public class Person
    {
        public string Name   // 没有声明后备字段
        {
            get; set;        // 访问器的方法体被声明为分号
        }
 
    }
        internal class Program
    {
        static void Main(string[] args)
        {
            Person person = new Person();
            Console.WriteLine(person.Name); // 想使用规则属性那样使用自动属性
            person.Name = "小王";
            Console.WriteLine(person.Name);
        }
    }

 

运行结果如下图所示:

参考资料

《C#图解教程(第4版)》——Daniel M. Solis

目录
相关文章
|
5月前
|
存储 安全 编译器
C# 11.0中的泛型属性:类型安全的新篇章
【1月更文挑战第23天】C# 11.0引入了泛型属性的概念,这一新特性为开发者提供了更高级别的类型安全性和灵活性。本文将详细探讨C# 11.0中泛型属性的工作原理、使用场景以及它们对现有编程模式的改进。通过深入了解泛型属性,开发者将能够编写更加健壮、可维护的代码,并充分利用C#语言的最新发展。
|
C# Windows 容器
C#或Winform中的消息通知之系统托盘的气泡提示窗口(系统toast通知)、ToolTip控件和ToolTipText属性
NotifyIcon控件表示系统右下角任务栏上的托盘图标,其ShowBalloonTip方法用于显示气球状提示框(Win10只有为本地Toast通知),ToolTip\oolTipText可以...
1895 0
C#或Winform中的消息通知之系统托盘的气泡提示窗口(系统toast通知)、ToolTip控件和ToolTipText属性
|
1月前
|
安全 C# 索引
C#一分钟浅谈:属性与索引器的定义
本文深入浅出地介绍了C#编程中的属性和索引器。属性让字段更安全,通过访问器方法在读写时执行额外操作,如验证数据有效性;索引器则赋予类数组般的访问方式,支持基于索引的数据访问模式。文章通过示例代码展示了如何定义及使用这两种特性,并提供了常见问题及其解决方案,帮助读者写出更健壮、易维护的代码。希望读者能从中学习到如何有效利用属性和索引器增强C#类的功能性。
68 12
|
5月前
|
存储 编译器 C#
|
4月前
|
开发框架 .NET 编译器
程序与技术分享:C#基础知识梳理系列三:C#类成员:常量、字段、属性
程序与技术分享:C#基础知识梳理系列三:C#类成员:常量、字段、属性
34 2
|
3月前
|
C#
C#中使用IntPtr.Size属性来判断当前系统是32位还是64位
这段代码首先检查 `IntPtr.Size`的值,如果是4,则输出"当前系统是32位";如果是8,则输出"当前系统是64位";如果都不是,就输出"未知系统位数"。
45 0
|
5月前
|
存储 JSON C#
C# 通过阿里云接口实现人脸属性识别
C# 通过阿里云接口实现人脸属性识别
|
5月前
|
Java C#
C#学习相关系列之多线程(七)---Task的相关属性用法
C#学习相关系列之多线程(七)---Task的相关属性用法
|
5月前
|
C#
C# Dev TreeList常用属性方法
C# Dev TreeList常用属性方法
|
5月前
|
开发框架 .NET C#
C# 10.0中的扩展属性与模式匹配:深入解析
【1月更文挑战第20天】C# 10.0引入了众多新特性,其中扩展属性与模式匹配的结合为开发者提供了更强大、更灵活的类型检查和代码分支能力。通过这一特性,开发者可以在不修改原始类的情况下,为其添加新的行为,并在模式匹配中利用这些扩展属性进行更精细的控制。本文将详细探讨C# 10.0中扩展属性与模式匹配的工作原理、使用场景以及最佳实践,帮助读者更好地理解和应用这一新功能。