C#属性介绍

简介: C#属性介绍


一、简要介绍

属性是代表类的实例或者类中的一个数据项的成员。

属性是字段和方法的交集,指的是一组两个匹配的访问器方法。

下面是属性的基本形式

public 返回类型 标识符{
    set 访问器为属性赋值;
    get 访问器为属性获取值;
}

属性包含两个代码块,分别以get和set关键字开头。

  • get块包含读取属性时候执行的语句
  • set块包含在向属性写入时执行的语句。

set访问器和get访问器的特点如下:

  • set访问器
  1. 拥有一个单独的、隐式的参数value,其类型与属性的相同
  2. set访问器返回类型为void
  • get访问器
  1. 没有参数
  2. 拥有一个与属性类型相同的返回值。

public 这样的修饰符是可选的,可以选择私有的,这样就不可以在类外直接访问 set 和 get 访问器

通常将类中的字段声明private以封装该字段, 然后声明一个public的属性来控制从类的外部对该字段的访问。

与属性关联的字段称为后备字段。

一般习惯把私有方法和字段以小写字母开头,公共方法和字段以大写字母开头。

使用属性和使用字段是一样的语法

  • 从属性取值时,编译器自动将字段风格的代码转换成对属性的get访问器的调用。
  • 向属性赋值时,编译器自动将字段风格的代码转换成对该属性的set访问器的调用。

二、详细介绍

2.1 例子

using System;
namespace PropertyDemo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            PropertyDemo propertyDemo = new PropertyDemo();
            propertyDemo.Name = "yyrwkk";
            Console.WriteLine(propertyDemo.Name);
            Console.ReadKey();
        }
    }
    public class PropertyDemo
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }
}

可以简化语句

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

2.2 属性和字段的比较

  1. 属性本质是方法而非字段。
  2. 只有在结构或类初始化好之后,才能通过该结构或类的属性赋值。
  3. 不能将属性作为ref或out参数传给方法,因为属性并不真正执行一个内存位置,它指向的是一个访问器方法。
  4. 属性最多只能包含一个get和一个set访问器,不能包含其他方法、字段和属性。
  5. get和set访问器不能获取任何参数。要赋的值会通过内建的、隐藏的value变量自动传给set访问器
  6. 不能声明const属性

属性跟字段的相同点

  • 都是命名的实例成员
  • 都有类型
  • 都可以被赋值和读取

属性和字段的不同点

  • 属性实际上是一个成员函数
  • 不为数据存储分配内存
  • 属性可以只读或者只写。

2.3 自动实现属性

允许只声明属性而不声明后备字段,编译器会创建隐藏的后备字段,并且自动挂接到get或者set访问器上。

自动实现属性的要点:

  1. 不声明后备字段,编译器根据属性的类型分配存储。
  2. 不能提供访问器的方法体。
  3. 自动实现的属性本身会自动分配内存。
  4. 可以创建只读自动属性,但是不能创建只写自动属性。
using System;
namespace PropertyDemo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            PropertyDemo propertyDemo = new PropertyDemo();
            propertyDemo.Name = "yyrwkk";
            Console.WriteLine(propertyDemo.Name);
            Console.ReadKey();
        }
    }
    public class PropertyDemo
    {
        //private string name;
        public string Name{get;set;}
    }
}

2.4 静态属性

属性可以声明为static,静态属性的访问器和所有静态成员一样。

  • 不能访问类的实例成员,但是可以访问类的静态成员
  • 当从类的外部访问时,必需使用类名进行引用。
using System;
namespace PropertyDemo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            PropertyDemo.Name = "yyrwkk";
            Console.WriteLine(PropertyDemo.Name);
            Console.ReadKey();
        }
    }
    public class PropertyDemo
    {
        //private string name;
        public static string Name {get;set;}
    }
}

2.5 只读/只写属性

可声明只含get访问器的属性,这称为只读属性,无法修改。

public string Name{
    get => name;
}

声明只含set访问器的属性,称为只写属性,无法读取。

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

只写属性适用于对密码这样的数据进行保护。

2.6 属性可访问性

声明属性时可以指定可访问性

在属性声明中,可以为set和get访问器单独指定可访问性,从而覆盖属性的可访问性

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

Name的get访问器就是public的,而Name的set访问器就是private的

2.7 接口声明属性

在接口中可以声明属性

interface Position{
    int X {get;set;}
    int Y {get;set;}
}

实现接口的任何类或者结构都必须实现X和Y属性。

接口中的属性不能指定访问修饰符。

2.8 使用初始化器初始化属性

使用属性初始化对象

using System;
namespace PropertyDemo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            PropertyDemo propertyDemo = new PropertyDemo() { Age=19,Name="yyrwkk" };
            Console.WriteLine(propertyDemo.Name);
            Console.ReadKey();
        }
    }
    public class PropertyDemo
    {
        public int Age { get; set; }
        public string Name { get; set; }
    }
}

调用对象初始化器,C#编译器会自动生成代码来调用默认构造器,然后调用每个具名属性的set访问器,把它们初始化成指定值。

还可以使用自定义的构造函数

using System;
namespace PropertyDemo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            PropertyDemo propertyDemo = new PropertyDemo(175) { Age=19,Name="yyrwkk" };
            Console.WriteLine(propertyDemo.Name);
            Console.ReadKey();
        }
    }
    public class PropertyDemo
    {
        private int height;
        public int Age { get; set; }
        public string Name { get; set; }
        public PropertyDemo(int height)
        {
            this.height = height;
        }
    }
}
相关文章
|
13天前
|
存储 安全 编译器
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可以...
1532 0
C#或Winform中的消息通知之系统托盘的气泡提示窗口(系统toast通知)、ToolTip控件和ToolTipText属性
|
13天前
|
C#
C# Dev TreeList常用属性方法
C# Dev TreeList常用属性方法
|
13天前
|
Java C#
C#学习相关系列之多线程(七)---Task的相关属性用法
C#学习相关系列之多线程(七)---Task的相关属性用法
|
13天前
|
开发框架 .NET C#
C# 10.0中的扩展属性与模式匹配:深入解析
【1月更文挑战第20天】C# 10.0引入了众多新特性,其中扩展属性与模式匹配的结合为开发者提供了更强大、更灵活的类型检查和代码分支能力。通过这一特性,开发者可以在不修改原始类的情况下,为其添加新的行为,并在模式匹配中利用这些扩展属性进行更精细的控制。本文将详细探讨C# 10.0中扩展属性与模式匹配的工作原理、使用场景以及最佳实践,帮助读者更好地理解和应用这一新功能。
|
13天前
|
运维 编译器 C#
C# 9.0中的本地函数属性:深化函数级别的控制
【1月更文挑战第17天】C# 9.0引入了本地函数属性的概念,允许开发者在本地函数上应用属性,从而进一步细化对函数行为的控制。这一新特性不仅增强了代码的可读性和可维护性,还为函数级别的编程提供了更多的灵活性。本文将探讨C# 9.0中本地函数属性的用法、优势以及可能的应用场景,帮助读者更好地理解并应用这一新功能。
|
13天前
|
XML 存储 JSON
C# | 使用Json序列化对象时忽略只读的属性
将对象序列化成为Json字符串是一个使用频率非常高的功能。Json格式具有很高的可读性,同时相较于XML更节省空间。 在开发过程中经常会遇到需要保存配置的场景,比如将配置信息保存在配置类型的实例中,再将这个对象序列化成为Json字符串并保存。当需要加载配置时,则是读取Json格式的字符串再将其还原成配置对象。在序列化的过程中,默认会将所有公开的属性和字段都序列化进入Json字符串中,这其中也会包含只读的属性或字段,而只读的属性和字段在反序列化的过程中其实是无意义的,也就是说这一部分存储是多余的。 本文将讲解如何在执行Json序列化时,忽略掉那些只读的属性和字段。
67 0
C# | 使用Json序列化对象时忽略只读的属性
|
6月前
|
前端开发 C# 开发工具
Unity快手上手【熟悉unity编辑器,C#脚本控制组件一些属性之类的】
Unity快手上手【熟悉unity编辑器,C#脚本控制组件一些属性之类的】
113 0
|
9月前
|
存储 编译器 C#
《More effective C#》第二章 尽量采用隐式属性来表示可变的数据
《More effective C#》第二章 尽量采用隐式属性来表示可变的数据
|
10月前
|
C#
C#属性的get与set
C#属性的get与set