C# 属性(Property)‌详解

news/2025/4/1 13:28:33/

在 C# 中,‌属性(Property)‌ 是类或结构体中的成员,用于封装对私有字段(称为 ‌backing field‌)的访问,提供更灵活和安全的数据操作方式。属性通过 get 和 set 访问器控制对数据的读写,是面向对象编程中封装思想的核心实践。


属性的核心作用‌

  • 封装数据‌:隐藏类的内部字段,通过属性暴露可控的访问接口。
  • 验证逻辑‌:在 set 访问器中添加数据验证逻辑。
  • 计算属性‌:动态生成值(例如根据其他字段计算)。
  • 简化语法‌:自动属性(Auto-Implemented Properties)让代码更简洁。

‌属性的基本语法‌

public class Person
{// 私有字段(backing field)private string _name;// 属性:控制对 _name 的读写public string Name{get { return _name; }set { _name = value?.Trim(); } // 示例:自动去除空格}
}

‌属性的常见类型‌

1. ‌自动实现属性(Auto-Implemented Property)‌
不需要手动定义 backing field,编译器自动生成。

public int Age { get; set; } // 默认可读写
public string Id { get; }     // 只读属性(只能在构造函数中赋值)

2. ‌计算属性(Computed Property)‌
根据其他字段动态返回值:

public class Rectangle
{public double Width { get; set; }public double Height { get; set; }// 计算面积(只读)public double Area => Width * Height;
}

3. ‌带有验证的属性‌
在 set 访问器中添加逻辑:

private int _age;
public int Age
{get => _age;set{if (value < 0)throw new ArgumentException("年龄不能为负数!");_age = value;}
}

4. ‌表达式体属性(C# 6+)‌
简化单行逻辑的属性:

public string FullName => $"{FirstName} {LastName}";

5. ‌Init-only 属性(C# 9+)‌
只能在对象初始化时赋值:

public string Name { get; init; }
// 使用:
var person = new Person { Name = "Alice" }; // 合法
person.Name = "Bob"; // 编译错误!

‌属性 vs 字段‌

‌字段(Field)‌‌属性(Property)‌
直接暴露数据,无访问控制。封装数据,通过 get/set 控制访问。
无法添加验证或逻辑。支持数据验证、动态计算等。
例如:public string Name;例如:public string Name { get; set; }

最佳实践‌

1‌、优先使用属性‌:避免直接暴露公有字段。
2‌、保持属性简单‌:避免在属性中编写复杂逻辑(应交给方法)。
‌3、只读属性‌:若数据不应被外部修改,使用 { get; private set; } 或 init。
‌4、线程安全‌:在属性中处理多线程访问时需加锁。

‌示例:完整用法‌

public class User
{private string _email;public string Email{get => _email;set{if (string.IsNullOrEmpty(value) || !value.Contains("@"))throw new ArgumentException("邮箱格式无效!");_email = value;}}// 自动属性 + 默认值public DateTime CreatedAt { get; } = DateTime.Now;
}// 使用:
var user = new User();
user.Email = "test@example.com"; // 合法
user.Email = "invalid";          // 抛出异常

掌握属性是 C# 开发的基础,它能显著提升代码的可维护性和健壮性。

文章来源:https://blog.csdn.net/pu_yu_hun_jin/article/details/146489334
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ppmy.cn/news/1583990.html

相关文章

逼用户升级Win11,微软开始给Win10限速

随着Windows10的支持时间越来越短&#xff0c;微软也加大了对Win10用户的驱赶力度。 最近&#xff0c;微软官宣了将要在今年6月份降低OneNote for Windows 10的同步速度。软件也将和Windows10在今年的10月14日一同停止支持和维护。 这将影响实时协作和多设备访问。 对OneNote…

#VCS# 关于 +incdir+XXX 和 -y 和 +libext+的区别

一 -y 和 -v 的区别 -y 和 -v 都是 VCS 中用于指定库文件或目录的选项,但它们在功能和使用方式上有重要区别: 1. -y (库目录指定) 功能:指定一个目录作为库目录,VCS 会在该目录中搜索模块定义 特点: 用于指定搜索路径,VCS 会在该目录下查找需要的模块 通常与 +libext…

【JavaScript】JavaScript Promises实践指南

【JavaScript】JavaScript Promises实践指南 你了解JavaScript中的Promises吗&#xff1f;这是一个很多人一开始就放弃的主题&#xff0c;但我会尽量让它变得尽可能简单。 1. “Promise”到底是什么&#xff1f; “Promise”是异步编程中的一个基本概念&#xff0c;特别是在J…

数据结构之约瑟夫环的问题

约瑟夫环&#xff08;Josephus problem&#xff09;是一个经典的数学问题&#xff0c;其大意是&#xff1a;N 个人围成一圈&#xff0c;每次数到第 M 个人被淘汰&#xff0c;直到最后剩下一个人。该问题在计算机科学、密码学等领域有广泛应用&#xff0c;例如进程调度、游戏规则…

React Native与原生Android数据传递

在 React Native (RN) 和 原生 Android 之间传递数据,主要有以下几种方式: Native Modules(原生模块) RN → Android:调用原生方法并传参 Android → RN:通过回调、Promise 或事件发送数据 Event Emitters(事件发射器) Android 主动发送事件给 RN Native UI Components…

0基础 | 制作麦克风音频放大电路

1. 声控LED放大电路 把一级放大电路想象成上一个里面的光敏电阻或者热敏电阻&#xff0c;下图所示 接下来将光敏电阻换成三极管&#xff0c;偏置电阻正好可以替代限流电阻1MΩ 至此完成了声控LED闪灯电路 Also 电压改为6v&#xff0c;适当给LED串联电阻&#xff0c;给基极放置…

LeetCode-451. 根据字符出现频率排序

1、题目描述: 给定一个字符串 s &#xff0c;根据字符出现的 频率 对其进行 降序排序 。一个字符出现的 频率 是它出现在字符串中的次数。 返回 已排序的字符串 。如果有多个答案&#xff0c;返回其中任何一个。 示例 1: 输入: s "tree" 输出: "eert"…

修改页面回显,整个项目如何同步

将文本框改为下拉框 在点位管理的界面中&#xff0c;通过区域的api向后端发送一个查询请求&#xff0c;后台会返回区域列表&#xff0c;在前端进行遍历展示即可。 复用现有的查询方法 引入区域api 代码小优化&#xff1a; 直接将要多次复用的代码抽取出来&#xff0c;以后要…