JAVA 和 C# Get Set 的区别

本文通过实例对比了Java和C#中属性访问的方法差异。Java使用传统的getter和setter方法,而C#则提供了更简洁的get和set块来实现相同的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 在JAVA和C#的属性访问里有着一些不同的地方..现将区别实例如下

 

Java的属性访问实例:

private String AAA;

 

public void GetAAA(){

    return AAA;

}

public void SetAAA(String AAA){

    this.AAA = AAA;

}

 

 

C#的属性访问实例:

 

private string AAA;

 

public string Get_SetAAA{

    get { return AAA; }

    set { AAA = value;}

}

<think>我们参考用户的问题之前的回答,来整理关于属性中SetGet区别以及基本赋值与属性使用场景的解释。用户的问题:我想了解属性中SetGet区别以及何时使用基本赋值与属性根据引用[1]引用[2]的内容,我们可以总结如下:1.属性(Properties)是一种特殊的类成员,提供对字段的灵活访问。2.属性通过getset访问器定义:-get访问器用于读取属性的值。-set访问器用于写入属性的值,并可以在写入时加入逻辑(如验证)。3.使用属性而不是直接使用public字段的原因:-封装性:可以控制对字段的访问(只读、只写、读写)。-可以在set访问器中加入数据验证逻辑,确保数据的有效性。-可以在属性值改变时触发事件或更新其他相关字段。4.基本赋值是指直接对字段(field)进行赋值操作,而属性赋值实际上是通过调用属性的set访问器来实现的,其中可以包含额外的逻辑。5.自动实现的属性(auto-implementedproperty)可以简化代码,当不需要额外的逻辑时,可以直接使用自动属性。因此,我们可以将回答组织如下:###一、属性的GetSet访问器的区别|**访问器**|**功能**|**使用场景**||------------|------------------------------|------------------------------------------------||**Get**|读取属性值|当外部代码需要获取属性值时,会调用get访问器。||**Set**|设置属性值(可包含验证逻辑)|当外部代码给属性赋值时,会调用set访问器。|-**Get访问器示例**:```csharpprivatestring_name;publicstringName{get{return_name;}//直接返回字段值}```-**Set访问器示例**:```csharpprivateint_age;publicintAge{set{if(value<0)//验证赋值是否合法thrownewArgumentException("年龄不能为负数");_age=value;//合法则赋值}}```###二、基本赋值与属性赋值的使用场景1.**基本赋值(直接对字段赋值)**:-仅在类内部使用,因为字段通常声明为`private`。-当不需要任何额外逻辑,直接赋值时使用。-示例:```csharppublicclassPerson{privatestring_name;//字段publicvoidSetName(stringname){_name=name;//基本赋值}}```2.**属性赋值**:-用于类外部对类成员的访问(通过属性)。-当需要控制赋值过程(如验证)或读取过程(如计算)时使用。-属性赋值实际上是通过调用set访问器来实现的,因此可以包含逻辑。-示例:```csharppublicclassPerson{privatestring_name;publicstringName{get=>_name;set{if(string.IsNullOrWhiteSpace(value))thrownewArgumentException("姓名不能为空");_name=value;//通过属性赋值(实际调用set访问器)}}}//外部使用Personp=newPerson();p.Name="张三";//属性赋值,会触发set访问器```###三、何时使用属性?何时使用基本赋值?-**使用属性的场景**:-需要公开给外部访问的字段(即作为类的公共接口)。-需要对赋值进行验证或转换。-需要在读取或写入时触发其他操作(如事件通知、日志记录等)。-需要实现只读或只写属性。-**使用基本赋值的场景**:-仅在类内部访问的私有字段。-不需要任何额外逻辑的直接赋值。###四、自动实现的属性当属性不需要额外的逻辑时,可以使用自动实现的属性简化代码:```csharppublicclassPerson{publicstringName{get;set;}//自动属性,编译器会自动生成一个隐藏的字段}```>**注意**:自动属性在编译时会自动生成一个隐藏的字段,并通过getset访问器访问该字段。如果后续需要添加逻辑,可以改为使用显式字段访问器。###五、封装性的重要性使用属性而不是public字段,是面向对象编程中封装性的体现。它有以下好处:1.控制访问权限(如只读、只写)。2.验证数据,保证对象状态的合法性。3.可以修改内部实现而不影响外部代码(例如,将自动属性改为有逻辑的属性)。###六、其他语言中的属性其他语言(如Java)中,属性通常通过gettersetter方法实现。例如:```javapublicclassPerson{privateStringname;publicStringgetName(){returnname;}publicvoidsetName(Stringname){if(name!=null&&!name.trim().isEmpty()){this.name=name;}}}```而在C#中,属性作为语言的一等公民,使用起来更加简洁自然。---§§相关问题§§1.C#中自动实现的属性与显式字段+属性在内存布局上有何差异?2.如何实现一个属性,在赋值时触发属性改变事件?3.在C#中,接口是否可以定义自动实现的属性?4.属性与索引器(indexer)在实现上有何异同点?[^1]:引用[1][^2]:引用[2]</think>### 属性中 Set Get区别及使用场景分析 #### 一、Set Get 的核心区别 | **访问器** | **作用** | **执行时机** | **典型应用** | |------------|---------------------------|--------------------------|----------------------------------| | **`Get`** | **读取属性值** | 访问属性时触发 | 返回字段值/执行计算逻辑[^1] | | **`Set`** | **写入属性值** | 赋值操作时触发 | 数据验证/触发事件/字段更新[^2] | ```csharp public class User { private string _name; // Get:读取时返回大写格式 public string Name { get => _name.ToUpper(); // 读取时处理数据 set { // Set:写入时验证 if (!string.IsNullOrWhiteSpace(value)) _name = value; // 验证通过后赋值 else throw new ArgumentException("姓名不能为空"); } } } ``` #### 二、基本赋值与属性赋值的本质区别 | **操作类型** | **底层机制** | **数据控制** | **典型场景** | |----------------|---------------------------|--------------------|----------------------------------| | **基本赋值** | 直接修改内存中的字段值 | 无控制逻辑 | 类内部的私有字段操作 | | **属性赋值** | 通过 `Set` 访问器间接修改 | 可添加控制逻辑 | 公共接口的数据交互[^1][^2] | ```csharp // 基本赋值(直接操作字段) private int _age; public void UpdateAge(int newAge) { _age = newAge; // 直接修改,无验证 } // 属性赋值(通过Set访问器) public int Age { set { if (value >= 0) // 数据验证 _age = value; } } ``` #### 三、何时使用属性 vs 基本赋值 **✅ 必须使用属性的场景**: 1. **数据验证需求** ```csharp public string Email { set { if (IsValidEmail(value)) // 自定义验证逻辑 _email = value; } } ``` 2. **值变更触发事件** ```csharp public decimal Balance { set { _balance = value; OnBalanceChanged(); // 触发余额变更事件 } } ``` 3. **计算属性/格式化输出** ```csharp public string FullName => $"{FirstName} {LastName}"; // Get计算属性 ``` 4. **访问控制需求** ```csharp public string ApiKey { get; private set; } // 外部只读,内部可写 ``` **✅ 适合基本赋值的场景**: 1. **类内部私有字段操作** ```csharp private List<Order> _orders = new(); public void ClearOrders() { _orders = new List<Order>(); // 内部直接重置 } ``` 2. **高性能关键路径**(避免属性访问器开销) ```csharp // 游戏循环中直接更新坐标 private Vector3 _position; public void UpdatePosition() { _position.x += 0.1f; // 直接操作字段 } ``` 3. **自动实现的简单属性** ```csharp public Guid Id { get; } = Guid.NewGuid(); // 无逻辑的只读属性 ``` #### 四、跨语言实现对比 | **语言** | **属性实现** | **特殊机制** | |-------------|---------------------------------------|---------------------------| | **C#** | `get`/`set` 访问器 + 表达式体属性 | 索引器、自动属性 | | **Java** | Getter/Setter 方法(`getName()`) | Lombok 注解生成 | | **Python** | `@property` 装饰器 | 描述符协议 | | **JavaScript** | Getter/Setter 函数 | `Object.defineProperty` | **Python 示例**: ```python class User: @property def name(self): # Getter return self._name.upper() @name.setter def name(self, value): # Setter if len(value) > 0: self._name = value ``` #### 五、设计原则总结 1. **封装性优先** 90% 的场景应使用属性替代公共字段,通过 `Set` 实现: - 数据验证 - 状态一致性维护 - 变更通知[^2] 2. **性能例外原则** 在性能关键路径(如高频循环)可谨慎使用直接字段访问 3. **只读公开原则** 对外暴露数据优先使用只读属性: ```csharp public int ImmutableId { get; } // 外部无法修改 ``` > **核心记忆点**: > - **`Get` = 数据出口**(控制如何读取) > - **`Set` = 数据入口**(控制如何写入) > - **属性 = 智能管道**(含处理逻辑的数据通道) > - **基本赋值 = 直接水管**(无控制的原始数据流) ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值