C# 字段与属性(get/set访问器、三种属性写法、只读属性)+属性拦截例子(get动态计算 + set数据校验)

一、字段 和 属性 终极区别(默写简答题)

核心口诀:字段存数据,属性做管控

  1. 使用场景不同:字段一般用于类内部使用;属性专门对外公开,供外部类读写数据

  2. 访问权限不同:字段默认 private(私有);属性基本都是 public(公共)

  3. 功能结构不同 :字段就是普通变量,仅用于存储数据;属性自带 get、set 访问器,可做数据拦截、校验

  4. 本质区别字段负责存储数据,属性不存数据,只负责读写拦截、逻辑校验


二、get / set 访问器 核心原理(必考)

1. 触发规则(对应你的代码)

  • 赋值时触发 set 访问器p.Name = "T"

  • 取值时触发 get 访问器Console.WriteLine(p.Name)

2. 关键字含义

  • get :读取访问器,必须 return 关联私有字段的值

  • set :赋值访问器,value 代表外部传入的赋值数据

3. 核心作用

属性可以在 set 中做数据校验、过滤、限制非法值,弥补字段直接赋值无校验的漏洞。

示例:你的代码禁止空字符串赋值

复制代码
set{
    Console.WriteLine("set访问器触发了"+value);
    if (value.Length==0)
    {
        throw new Exception("不能赋空字符串");
    }
    _name = value; 
}

三、C# 三种属性完整写法(全覆盖)

写法1:完整属性写法(最原始、可自由写逻辑)

适用:需要复杂校验、拦截逻辑

复制代码
//1.先定义私有字段
private string _name;
//2.定义公共属性
public string Name 
{
    get{
        Console.WriteLine("get访问器触发了");
        return _name; 
    }
    set{
        Console.WriteLine("set访问器触发了"+value);
        if (value.Length==0)
        {
            throw new Exception("不能赋空字符串");
        }
        _name = value; 
    }
}

写法2:简写属性(Lambda 表达式写法)

适用:逻辑简单,无需复杂校验,精简代码

复制代码
private int _a1;
public int A1 { get => _a1; set => _a1 = value; }

写法3:自动属性(语法糖写法、项目最常用)

适用:不需要任何拦截逻辑,纯读写数据

编译器会自动帮我们生成隐藏私有字段,无需手动声明

复制代码
// 带默认值的自动属性
public string Id { get; set; } = "001";

四、只读属性(重点考点)

1. 定义规则

只写 get 、不写 set,属性变为只读属性

外部只能读取,无法赋值修改

2. 你的代码示例

复制代码
public string Msg { get; }

报错场景:

复制代码
p3.Msg = "S"; // 报错!只读属性不能赋值

五、代码执行流程解析

复制代码
People p = new People();   
p.Name = "T";       // 赋值 → 触发 set 访问器
Console.WriteLine(p.Name); // 取值 → 触发 get 访问器

People p3 = new People();
p3.Name = "Y";
Console.WriteLine(p3.Name+":"+p3.Id);

每一个对象的属性都是独立数据,互不干扰。


六、终极考点总结(背诵)

  • 字段存数据,属性控读写

  • 外部赋值触发 set,外部取值触发 get

  • value 是 set 专属关键字,代表外部传入的值

  • 自动属性:系统自动生成隐藏字段,最简写法,项目首选

  • 只有get没有set → 只读属性,禁止赋值

  • 属性最大优势:可以在set中做数据校验,保证数据安全

------------属性拦截例子(get动态计算 + set数据校验)------------

一、代码核心功能概述

本案例演示 属性 get/set 拦截的两大核心用法

  • set 拦截:对外部传入的数据做合法性校验,非法数据直接抛异常,保护数据安全

  • get 拦截:取值时动态加工数据,不直接返回原值,实现动态计算效果


二、年龄属性 Age 逐行精讲(高频考点)

1. 底层字段

复制代码
private int _age;

私有字段,专门用于存储真实年龄数据,外部无法直接访问。

2. set 赋值拦截(数据校验)

复制代码
set
{
    if (value < 0||value>20)
    {
        throw new Exception("年龄不在合适的范围内");
    }
    _age = value; 
}

校验规则 :年龄只能在 0~20 之间

非法场景:赋值负数、大于20的数字 → 直接抛出程序异常,阻止非法数据存入字段

合法场景:赋值 0-20 数值 → 正常给私有字段 _age 赋值

3. get 取值拦截(动态计算)

复制代码
get
{
    _age *= 10;
    return _age; 
}

超级重点(易错坑)

每次读取 Age 属性,都会执行一次:原值 * 10 ,并且修改底层字段真实值

4. 执行流程拆解(你的代码运行过程)

复制代码
d1.Age = 19;  // set触发:19合法,_age = 19
Console.WriteLine(d1.Age); // get触发:_age = 19*10 = 190,输出190

如果多次取值,会叠加翻倍(每读一次 ×10)


三、颜色属性 Color 精讲(集合匹配校验)

1. 预设合法数据

复制代码
private char[] colors = { '黄', '白', '黑' };

规定:狗狗颜色只能是黄、白、黑三种

2. 颜色校验逻辑

复制代码
set 
{
    if (!colors.Contains(value))
    {
        throw new Exception("颜色不合适");
    }
    _color = value;
}

逻辑:判断用户赋值的颜色 是否不在合法数组中

不匹配 → 抛异常拦截;匹配 → 正常存入字段

3. 正常运行代码

复制代码
d1.Color = '白'; // 合法
Console.WriteLine(d1.Color);

四、public int a=100; 易错对比

复制代码
public int a=100;

这是 公共字段,不是属性!

无 get、无 set、无任何拦截、无校验,外部可以随意赋值负数、乱值,数据不安全。

对比结论:字段直接暴露不安全,属性封装可校验、可管控。


五、本题两大核心考点(考试必考)

1. set 访问器作用

对外部赋值的数据进行过滤、校验、限制,保证类内部数据的合法性与安全性。

2. get 访问器作用

可以对原始数据二次加工、动态计算、格式转换后再返回给外部,不改变外部赋值逻辑。


六、超级易错坑点(必背)

  • get 里面如果修改字段值,会永久改变底层数据,每次读取都会叠加效果

  • set 中 value 是固定关键字,代表外部赋进来的值

  • 字段公开直接赋值无校验,属性可以精准拦截非法数据

  • Contains() 可以判断值是否存在于数组/集合中,常用于固定范围校验


七、简答题满分总结

为什么要用属性封装字段?

为了保证数据安全,通过 set 访问器可以对赋值数据进行合法性校验,拦截非法数据;通过 get 访问器可以对返回数据进行动态加工处理,同时隐藏私有字段,符合面向对象封装特性。

相关推荐
影寂ldy1 小时前
C#栈和队列
开发语言·c#
SilentSamsara1 小时前
SQLAlchemy 2.x:异步 ORM 与数据库迁移 Alembic 完整指南
开发语言·数据库·python·sql·青少年编程·oracle·fastapi
basketball6162 小时前
C++ static_cast 完全解析
开发语言·c++
魔法阵维护师2 小时前
从零开发游戏需要学习的c#模块,第三十四章(设置界面)
学习·游戏·c#
子安柠2 小时前
Go语言并发编程:协程与管道详解
开发语言·后端·golang
gc_22992 小时前
学习C#调用OpenXml操作word文档的基本用法(39:学习表格类-1)
c#·word·表格·table·openxml
程序大视界2 小时前
【Python系列课程】Python面向对象(下):封装、继承与多态
开发语言·python
Lumbrologist2 小时前
【C++】零基础入门 · 第 12 节:模板与 STL 入门
开发语言·c++
天月风沙2 小时前
基于机器视觉的实验室器件仓储系统设计——内蒙古自治区国家级大创工程存档
开发语言·python