C#调用一个类中的字段属性,使用get、set,应该如何编写代码
时间: 2025-08-25 16:19:30 浏览: 2
<think>好的,用户想了解如何在C#中使用get和set访问类中的字段属性,需要代码示例。我需要结合之前的回答和提供的引用内容来生成一个清晰的解答。
首先,用户的上一次回答已经详细讲解了get和set的基础用法、显式属性、自动属性、访问权限控制等,并给出了代码示例。现在用户再次提问,可能希望得到更简洁直接的示例,或者想深入理解某些部分。
根据用户提供的引用,引用[1]解释了属性的基本概念和语法,引用[2]和[3]展示了显式属性和自动属性的例子,引用[4]对比了使用属性与公共字段的区别,并提到了封装的优势。需要确保回答涵盖这些方面,同时提供代码示例。
用户可能需要区分显式属性和自动属性的不同使用场景,比如当需要添加验证逻辑时使用显式属性,而自动属性适用于简单情况。此外,访问权限控制如只读或只写属性也是重点。
需要确保代码示例正确,符合C#语法,并标注不同版本的特性,如自动属性初始化在C#6+支持。同时,要解释每个示例的作用,比如数据验证、延迟加载等,以帮助用户理解应用场景。
可能还需要回答用户潜在的疑问,比如为什么使用属性而不是公共字段,以及如何实现不同的访问权限。此外,引用之前的回答中的常见问题,比如Q1关于属性与公有字段的区别,可以加强回答的全面性。
最后,按照用户要求,生成相关问题,帮助用户进一步学习,比如数据绑定、init访问器、反射等高级主题。确保引用标记正确,参考提供的引用来源,但用户提供的引用编号可能与之前不同,需要调整引用标记,比如引用[^1][^2][^3][^4]对应到之前的回答中的引用来源。</think>### C# 使用 `get` 和 `set` 访问类字段属性的代码示例
---
#### **1. 基础示例:显式属性(手动控制字段)**
通过私有字段 `_name` 和属性 `Name` 实现数据封装,`get` 返回字段值,`set` 对输入值做校验:
```csharp
public class Person
{
private string _name; // 私有字段
// 显式属性:添加校验逻辑
public string Name
{
get { return _name; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("姓名不能为空");
_name = value.Trim();
}
}
}
```
- **用法**:
```csharp
var person = new Person();
person.Name = " Alice "; // 赋值时会自动调用 set,修剪空格 → "Alice"
Console.WriteLine(person.Name); // 调用 get 返回字段值
```
---
#### **2. 自动属性(简化代码)**
编译器自动生成隐藏字段,适合无需额外逻辑的场景:
```csharp
public class Product
{
public string Id { get; set; } // 可读写自动属性
public decimal Price { get; set; } // 初始化默认值(C# 6+)
public DateTime CreatedAt { get; } = DateTime.Now; // 只读自动属性
}
```
- **初始化**:直接赋默认值(如 `Price` 和 `CreatedAt`)。
---
#### **3. 访问权限控制**
通过 `private set` 或 `protected set` 限制修改权限:
```csharp
public class Account
{
public string Username { get; private set; } // 外部只读,类内可修改
// 构造函数中初始化只读属性
public Account(string username)
{
Username = username; // 允许在构造函数中赋值
}
}
```
---
#### **4. 高级用法:延迟加载**
通过 `get` 访问器实现按需加载数据:
```csharp
public class DataLoader
{
private List<string> _cachedData;
public List<string> Data
{
get
{
if (_cachedData == null)
_cachedData = LoadDataFromDatabase();
return _cachedData;
}
}
private List<string> LoadDataFromDatabase() => new List<string> { "A", "B", "C" };
}
```
---
#### **5. 表达式体属性(C# 7+)**
简化单行逻辑的写法:
```csharp
public class Vector
{
public double X { get; set; }
public double Y { get; set; }
// 只读计算属性
public double Magnitude => Math.Sqrt(X * X + Y * Y);
// 带校验的 set 简化写法
private int _score;
public int Score
{
get => _score;
set => _score = value >= 0 ? value : 0; // 输入负值时自动归零
}
}
```
---
### **对比:属性 vs 公有字段**
```csharp
// 公有字段(不推荐)
public class BadExample
{
public int Age; // 直接暴露,无法控制赋值逻辑
}
// 使用属性(推荐)
public class GoodExample
{
private int _age;
public int Age
{
get => _age;
set => _age = value >= 0 ? value : 0; // 自动过滤负值
}
}
```
- **属性优势**:数据校验、逻辑扩展、兼容性[^4]。
---
### **完整代码示例**
```csharp
public class Student
{
// 自动属性 + 初始化
public string StudentId { get; set; } = "S001";
// 显式属性 + 校验
private int _grade;
public int Grade
{
get => _grade;
set
{
if (value < 1 || value > 12)
throw new ArgumentException("年级无效");
_grade = value;
}
}
// 只读属性(构造函数赋值)
public string EnrollmentYear { get; }
public Student(string year)
{
EnrollmentYear = year;
}
}
```
---
### **相关问题**
1. **如何在 WPF 中使用属性实现双向数据绑定(`INotifyPropertyChanged`)?**
2. **C# 中 `init` 关键字(C# 9.0)与 `set` 有何区别?**
3. **如何通过反射动态获取或设置属性的值?**
4. **自动属性与显式属性的性能差异是什么?**
若有更多疑问,欢迎继续交流!
阅读全文
相关推荐


















