在C#中,修饰符用于定义类、结构体、成员变量、方法等的访问权限、行为特性或约束条件。以下是C#修饰符的分类及详细说明,附有代码示例:
一、访问修饰符
控制类或成员的可见性和访问范围。
-
public
- 作用:公开访问,无任何限制。
- 适用对象:类、结构体、成员(字段、方法、属性等)。
csharppublic class MyClass { public int PublicField; // 任何地方均可访问 }
-
private
- 作用:仅在声明它的类或结构体内部可访问。
- 默认修饰符:类成员(未显式指定时)。
csharpclass MyClass { private int _privateField; // 仅限本类内部访问 }
-
protected
- 作用:在本类及派生类中可访问。
csharpclass BaseClass { protected int ProtectedField; // 本类和子类可访问 } class DerivedClass : BaseClass { void AccessProtected() { ProtectedField = 10; // 允许访问 } }
-
internal
- 作用:同一程序集(.dll或.exe)内可访问。
- 默认修饰符:类和结构体(未显式指定时)。
csharpinternal class InternalClass { internal int InternalField; // 同一程序集内可访问 }
-
protected internal
- 作用:同一程序集内或派生类(即使在不同程序集)中可访问。
csharppublic class BaseClass { protected internal int ProtectedInternalField; }
-
private protected(C# 7.2+)
- 作用:仅在同一程序集中的派生类可访问。
csharppublic class BaseClass { private protected int PrivateProtectedField; }
二、非访问修饰符
定义类或成员的行为特性或约束。
-
static
- 作用:声明静态成员或类,属于类型而非实例。
csharppublic static class MathUtils { public static int Add(int a, int b) => a + b; // 静态方法 public static readonly double PI = 3.14; // 静态字段 } // 调用:MathUtils.Add(1, 2);
-
readonly
- 作用:字段只能在声明时或构造函数中赋值。
csharpclass MyClass { public readonly int ReadonlyField; public MyClass(int value) { ReadonlyField = value; // 构造函数中初始化 } }
-
const
- 作用:声明编译时常量,隐式静态且必须初始化。
csharppublic class Constants { public const int MaxValue = 100; // 编译时常量 }
-
abstract
- 作用:定义抽象类或抽象方法(无实现,需在派生类中实现)。
csharppublic abstract class Animal { public abstract void Speak(); // 抽象方法 } public class Dog : Animal { public override void Speak() => Console.WriteLine("Woof"); // 必须实现 }
-
sealed
- 作用:阻止类被继承,或方法被重写。
csharppublic sealed class SealedClass { } // 不能被继承 public class Base { public virtual void Method() { } } public class Derived : Base { public sealed override void Method() { } // 禁止进一步重写 }
-
virtual 和 override
- virtual:允许方法在派生类中被重写。
- override:重写基类的虚方法或抽象方法。
csharppublic class Base { public virtual void Show() => Console.WriteLine("Base"); } public class Derived : Base { public override void Show() => Console.WriteLine("Derived"); }
-
async
- 作用 :声明异步方法,通常与
await
配合使用。
csharppublic async Task<int> FetchDataAsync() { await Task.Delay(1000); return 42; }
- 作用 :声明异步方法,通常与
-
partial
- 作用:允许类、结构体或方法分布在多个文件中。
csharp// File1.cs public partial class MyClass { public void MethodA() { } } // File2.cs public partial class MyClass { public void MethodB() { } }
-
unsafe
- 作用:允许使用指针和非托管代码。
csharppublic unsafe void PointerExample() { int value = 10; int* ptr = &value; Console.WriteLine(*ptr); // 输出10 }
三、其他修饰符
-
volatile
- 作用:标记字段可能被多线程修改,禁止编译器优化。
csharppublic class Worker { private volatile bool _stopFlag; // 确保多线程可见性 }
-
extern
- 作用:声明外部方法(通常在非托管代码中实现)。
csharppublic class ExternalExample { [DllImport("user32.dll")] public static extern int MessageBox(IntPtr hWnd, string text, string caption, int options); }
四、修饰符的组合与限制
- 不允许的组合 :
abstract
与sealed
(抽象类不能被密封)。static
与virtual/override
(静态成员不能被重写)。
- 常见约束 :
const
字段隐式为static
,不能与static
显式组合。readonly
字段可以是实例或静态,但必须在构造函数或声明时初始化。
五、总结
C#修饰符通过控制访问性和行为特性,增强了代码的封装性、安全性和灵活性。合理使用修饰符可以:
- 明确类型和成员的可见范围(如
public
、private
)。 - 定义静态或常量的全局行为(如
static
、const
)。 - 支持面向对象特性(如
abstract
、virtual
)。 - 处理多线程或非托管代码(如
volatile
、unsafe
)。
理解这些修饰符的用途和限制,是编写高质量C#代码的关键。