C# 属性(Property)‌详解

在 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# 开发的基础,它能显著提升代码的可维护性和健壮性。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iPhone 16如何翻译文档?文档翻译技巧、软件推荐

在全球化的今天&#xff0c;跨语言交流变得越来越频繁&#xff0c;而文档翻译更是成为许多人日常工作和学习中的重要需求。作为苹果公司最新推出的旗舰机型&#xff0c;iPhone 16凭借其强大的硬件性能和丰富的软件生态&#xff0c;为我们提供了多种便捷的文档翻译方式&#xff…

HRP方法全文总结与模型流程解析

背景与问题 传统二次优化方法&#xff08;如Markowitz的CLA&#xff09;存在三大问题&#xff1a; 不稳定性&#xff1a;协方差矩阵的高条件数导致逆矩阵计算误差放大&#xff0c;权重剧烈波动。 集中性&#xff1a;优化结果过度集中于少数资产&#xff0c;易受个体风险冲击。…

解决项目一直在构建中的问题:以 IntelliJ IDEA 为例提高共享堆内存

在使用 IntelliJ IDEA 时&#xff0c;开发者可能会遇到项目长期处于构建状态的问题。这种情况将严重影响开发效率。通常&#xff0c;这种问题的一个常见原因是构建进程所分配的堆内存不足。本文将以 IntelliJ IDEA 为背景&#xff0c;介绍如何通过提高共享堆内存来解决此问题&a…

金橙子删除打标对象

注意在使用金橙子根据对象名称删除对象时要注意,每删除一个对象,所有对象的索引都将改变。 如果你是用for去遍历,再根据索引获取打标对象名称的话就会出现漏的掉的问题。 改进方法 1,将要删除的对象找到后,统一存放在一个集合中。再根据这个要删除的对象集合再一个个去遍…

JVM常见概念之条件移动

问题 当我们有分支频率数据时&#xff0c;有什么有趣的技巧可以做吗&#xff1f;什么是条件移动&#xff1f; 基础知识 如果您需要在来自一个分支的两个结果之间进行选择&#xff0c;那么您可以在 ISA 级别做两件不同的事情。 首先&#xff0c;你可以创建一个分支&#xff…

MANISKILL3:GPU 并行机器人模拟和渲染,用于通用的具身AI

本文介绍了一种名为ManiSkill3的机器人仿真系统&#xff0c;它采用了GPU并行化技术&#xff0c;并针对通用性进行了优化。该系统支持多种视觉输入方式和异构模拟&#xff0c;能够在物理场景中进行高效的仿真和渲染&#xff0c;达到比其他平台更快的速度和更少的GPU内存使用量。…

计算机网络高频(三)UDP基础

计算机网络高频(三)UDP基础 1.UDP的头部格式是什么样的?⭐ UDP 头部具有以下字段: 源端口(Source Port):16 位字段,表示发送方的端口号。目标端口(Destination Port):16 位字段,表示接收方的端口号。长度(Length):16 位字段,表示 UDP 数据报(包括头部和数据部…

微信小程序中使用Less样式方法

在微信小程序中使用Less样式&#xff0c;可以通过以下步骤实现。主要原理是借助Visual Studio Code&#xff08;VSCode&#xff09;的插件将Less文件自动编译为小程序支持的.wxss文件&#xff0c;或通过微信开发者工具的扩展功能直接集成Less编译环境。以下是具体方法&#xff…

Leetcode 刷题笔记 图论part05

卡码网 107 寻找存在的路径 初识并查集 并查集功能&#xff1a; 寻找根节点&#xff0c;函数: find(int u)&#xff0c;也就是判断这个节点的祖先节点是哪个将两个节点接入到同一个集合&#xff0c;函数: join(int u, int v)&#xff0c;将两个节点连在同一个根节点上判断两…

SpringBoot星之语明星周边产品销售网站设计与实现

在当今数字化时代&#xff0c;明星周边产品的线上销售已成为一种趋势。幽络源作为一站式综合平台&#xff0c;不仅提供免费源码、网络兼职资源&#xff0c;还分享各类技术教程。本文将详细介绍基于SpringBoot的星之语明星周边产品销售网站的设计与实现&#xff0c;帮助开发者快…

怎样对比找到两个git仓库的差异

怎样对比找到两个git仓库的差异 陈拓 2024/12/24-2024/12/28 1. 概述 要比较两个Git仓库的差异&#xff0c;可以使用git diff命令。你需要先将两个仓库的克隆版本都检出到本地&#xff0c;然后在对应的目录中运行git diff命令。 下面我们以YDLIDAR ROS2驱动程序ydlidar_ros2…

C语言-装饰器模式详解与实践 - LED控制系统

文章目录 C语言装饰器模式详解与实践 - LED控制系统1. 什么是装饰器模式&#xff1f;2. 为什么需要装饰器模式&#xff1f;3. 实际应用场景4. 代码实现4.1 头文件 (led_decorator.h)4.2 实现文件 (led_decorator.c)4.3 使用示例 (main.c) 5. 代码分析5.1 关键设计点5.2 实现特点…

Go常见问题与回答(下)

文章目录 1、通过指针变量 p 访问其成员变量 name&#xff0c;有哪几种方式&#xff1f;2、代码&#xff0c;说出结果3、扩容提&#xff0c;代码&#xff0c;说出结果4、指出下面这段代码的错误之处5、是否通过编译6、关于字符串连接&#xff0c;下面语法正确的是7、关于iota&a…

JVM 核心知识点总结

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

SQL中体会多对多

我们可以根据学生与课程多对多关系的数据库模型&#xff0c;给出实际的表数据以及对应的查询结果示例&#xff0c;会用到JOINLEFT JOIN两种连接 1. 学生表&#xff08;students&#xff09; student_idstudent_name1张三2李四3王五 2. 课程表&#xff08;courses&#xff09…

ES如果要查10条数据需要从各个分片上各取多少条数据?

目录 ES如果要查10条数据需要从各个分片上各取多少条数据? 简单查询(如 match_all 或 term 查询) 深度分页查询(如 from + size 查询) 聚合查询 什么叫聚合查询? 聚合查询的基本结构 常见的聚合类型 聚合查询的执行过程 聚合查询的示例 聚合查询的应用场景 注意…

人机交互自学引导

第1关&#xff1a;输出“Hello World!” # 在下面一行补充代码&#xff0c;输出“Hello World!” print(Hello World!) 第2关&#xff1a;输出“李白&#xff0c;你好&#xff01;” # 在下面补充代码&#xff0c;在两行中依次输出“李白&#xff0c;你好&#xff01;”和“…

CentOS 7 更换 yum 源(阿里云)+ 扩展 epel 源

CentOS 7 更换 yum 源&#xff08;阿里云&#xff09; 扩展 epel 源 一、备份现有 yum 源二、下载 yum 源&#xff08;任选其一即可&#xff09;三、清理并生成缓存四、安装 EPEL 扩展源&#xff08;根据需要下载&#xff09;五、验证是否生效六、一键脚本&#xff08;阿里云源…

无人机与传统巡检优劣势对比!

一、无人机巡检的优势 1. 高效性 覆盖范围广&#xff1a;可快速扫描大范围区域&#xff08;如电力线路、管道、农田等&#xff09;&#xff0c;尤其适合复杂地形&#xff08;山区、沼泽等&#xff09;。 速度快&#xff1a;飞行速度远高于人工巡检&#xff0c;缩短任务周期…

DrRacket是一款专为Scheme和Racket编程语言设计的集成开发环境(IDE)

DrRacket是一款专为Scheme和Racket编程语言设计的集成开发环境&#xff08;IDE&#xff09;&#xff0c;由瑞士苏黎世联邦理工学院开发。它不仅是初学者学习编程的理想工具&#xff0c;也适用于专业级开发‌。 安装DrRacket 请访问https://download.racket-lang.org安装Racke…