set-get方法的使用

在 C# 中,get 和 set 主要用于定义属性(Property),属性是一种用于封装字段(Field)的成员,它提供了对字段的访问控制,使得可以更安全、更方便地读取和修改字段的值。以下是关于 get 和 set 的详细介绍:

1. 属性的基本概念

属性结合了字段和方法的优点,从外部看它就像一个字段,可以像访问字段一样访问属性;但在内部,它通过 get 和 set 访问器来控制对字段的读写操作。

2. 完整属性定义(包含 get 和 set)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Person
{
// 私有字段,用于存储数据
private string _name;

// 公共属性,用于封装 _name 字段
public string Name
{
get
{
// get 访问器用于获取属性的值
return _name;
}
set
{
// set 访问器用于设置属性的值
// value 是一个隐式参数,代表要设置的值
_name = value;
}
}
}

class Program
{
static void Main()
{
Person person = new Person();
// 设置属性值,调用 set 访问器
person.Name = "John";
// 获取属性值,调用 get 访问器
Console.WriteLine(person.Name);
}
}

在上述代码中:

_name 是一个私有字段,用于实际存储数据。
Name 是一个公共属性,它封装了 _name 字段。
get 访问器用于返回 _name 字段的值,当从外部读取 Name 属性时,会执行 get 访问器中的代码。
set 访问器用于设置 _name 字段的值,当从外部给 Name 属性赋值时,会执行 set 访问器中的代码,value 是一个隐式参数,它代表要设置的新值。

3. 只读属性(只包含 get 访问器)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Circle
{
private double _radius;

public Circle(double radius)
{
_radius = radius;
}

// 只读属性,只有 get 访问器
public double Area
{
get
{
return Math.PI * _radius * _radius;
}
}
}

class Program
{
static void Main()
{
Circle circle = new Circle(5);
// 可以读取 Area 属性的值
Console.WriteLine(circle.Area);
// 下面这行代码会报错,因为 Area 是只读属性
// circle.Area = 100;
}
}

在这个例子中,Area 属性只有 get 访问器,没有 set 访问器,所以它是只读的。外部代码只能读取该属性的值,不能对其进行赋值操作。

4. 自动实现属性(简化属性定义)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Book
{
// 自动实现属性,编译器会自动生成一个隐藏的私有字段
public string Title { get; set; }
public string Author { get; set; }
}

class Program
{
static void Main()
{
Book book = new Book();
book.Title = "C# Programming";
book.Author = "John Doe";
Console.WriteLine($"Title: {book.Title}, Author: {book.Author}");
}
}

在自动实现属性中,不需要显式定义私有字段,编译器会自动生成一个隐藏的私有字段。可以直接使用 get 和 set 访问器,代码更加简洁。

5. 访问修饰符与 get、set

可以为 get 和 set 访问器分别指定不同的访问修饰符,以实现更细粒度的访问控制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Student
{
private int _age;

public int Age
{
get
{
return _age;
}
private set
{
if (value >= 0)
{
_age = value;
}
}
}

public Student(int age)
{
// 类内部可以调用私有 set 访问器
Age = age;
}
}

class Program
{
static void Main()
{
Student student = new Student(20);
// 可以读取 Age 属性的值
Console.WriteLine(student.Age);
// 下面这行代码会报错,因为 set 访问器是私有的
// student.Age = 21;
}
}

在这个例子中,Age 属性的 set 访问器被声明为 private,这意味着只有在 Student 类内部才能修改 Age 属性的值,外部代码只能读取该属性的值。



Csharp public与private的权限控制

访问修饰符的概念

在 C# 中,访问修饰符用于控制类、成员(如字段、方法、属性等)的可访问性。publicprivate是两种最常用的访问修饰符。它们定义了代码中的哪些部分可以访问特定的类成员。

private访问修饰符

含义:private是最严格的访问级别。被标记为private的成员只能在其所属的类内部访问。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MyClass
{
private int myPrivateVariable;
private void MyPrivateMethod()
{
// 这个方法可以访问myPrivateVariable
myPrivateVariable = 10;
}
}
class AnotherClass
{
public void Test()
{
MyClass myObj = new MyClass();
// 下面这行代码会导致编译错误,因为myPrivateVariable是私有的,不能在MyClass外部访问
// myObj.myPrivateVariable = 5;
// 下面这行代码会导致编译错误,因为MyPrivateMethod是私有的,不能在MyClass外部访问
// myObj.MyPrivateMethod();
}
}

用途:

用于隐藏类的内部实现细节。例如,一个类可能有一些内部的计数器或者状态变量,这些变量不应该被外部代码随意修改,就可以将它们声明为private。这样可以确保类的完整性和一致性,防止外部代码对内部数据进行不恰当的操作。
限制对方法的访问。有些方法可能只是为了辅助类内部的其他方法而存在,不应该被外部调用,将这些方法声明为private可以避免它们被误用。

public访问修饰符

含义:public提供了最广泛的访问级别。被标记为public的成员可以从任何其他类访问,无论是在同一个程序集中还是在引用了该程序集的其他程序集中。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyClass
{
public int myPublicVariable;
public void MyPublicMethod()
{
// 这个方法可以被其他类访问
myPublicVariable = 20;
}
}
class AnotherClass
{
public void Test()
{
MyClass myObj = new MyClass();
myObj.myPublicVariable = 5;
myObj.MyPublicMethod();
}
}

用途:

当需要向外部提供类的功能或者数据时使用。例如,一个表示图形的类可能有一个public方法用于绘制图形,或者一个表示数据库连接的类可能有public属性用于获取连接字符串。这些public成员构成了类与外部世界交互的接口,其他类可以通过这些接口来使用该类的功能。

protected(受保护的)

含义:被 protected 修饰的成员可以在其所属的类内部以及该类的派生类中访问。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
class MyBaseClass
{
protected int myProtectedVariable;
}
class MyDerivedClass : MyBaseClass
{
public void MyDerivedMethod()
{
// 可以访问myProtectedVariable,因为MyDerivedClass继承自MyBaseClass
myProtectedVariable = 20;
}
}

internal(内部的)

含义:被 internal 修饰的成员可以在同一程序集(一个.dll 或.exe 文件)内的任何类中访问。

示例:

1
2
3
4
5
6
7
internal class MyInternalClass
{
internal void MyInternalMethod()
{
// 方法体
}
}

如果有另一个类在相同的程序集中,就可以访问MyInternalClass和MyInternalMethod,但如果在其他程序集中则无法访问。

protected internal(受保护的内部)

含义:这是一种组合修饰符。被 protected internal 修饰的成员可以在其所属的类内部、该类的派生类中或者同一程序集内的任何类中访问。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
class MyBaseClass2
{
protected internal int myProtectedInternalVariable;
}
class MyDerivedClass2 : MyBaseClass2
{
public void MyDerivedMethod2()
{
// 可以访问myProtectedInternalVariable,因为是派生类
myProtectedInternalVariable = 30;
}
}

同时,在同一程序集中的其他类也可以访问myProtectedInternalVariable。