404 Not Found

404 Not Found


nginx

静态成员与扩展方法

static 字段与方法

static 成员属于类型本身,而非某个实例。所有实例共享同一份 static 字段,static 方法通过 类名.成员 调用,无需创建对象。

示例

CSHARP
class Counter
{
    public static int TotalCount = 0;
    public int InstanceId;

    public Counter(int id)
    {
        InstanceId = id;
        TotalCount++;
    }

    public static void Report()
    {
        Console.WriteLine($"已创建 {TotalCount} 个实例");
    }
}

Counter a = new Counter(1);
Counter b = new Counter(2);
Counter.Report();
Console.WriteLine(Counter.TotalCount);
▶ 试一试
TEXT
已创建 2 个实例
2
💡 static 方法中不能使用 this,也不能直接访问实例成员,只能访问其他 static 成员。

静态构造函数

静态构造函数在类首次被访问时自动执行一次,且仅一次。它不能有访问修饰符和参数,常用于初始化 static 字段。

示例

CSHARP
class Config
{
    public static readonly DateTime StartTime;

    static Config()
    {
        StartTime = DateTime.Now;
        Console.WriteLine("静态构造函数已执行");
    }
}

Console.WriteLine("准备访问 Config");
Console.WriteLine(Config.StartTime);
Console.WriteLine(Config.StartTime);
▶ 试一试
TEXT
准备访问 Config
静态构造函数已执行
2026/06/28 10:00:00
2026/06/28 10:00:00
⚠️ 静态构造函数只触发一次,即使多次访问该类的 static 成员也不会重复执行。

static 类(工具类模式)

static class 声明的类不能被实例化,也不能被继承,所有成员必须都是 static 的,适合封装工具方法。

示例

CSHARP
static class MathHelper
{
    public static double Square(double x) => x * x;
    public static double Hypotenuse(double a, double b) => Math.Sqrt(Square(a) + Square(b));
}

Console.WriteLine(MathHelper.Square(3));
Console.WriteLine(MathHelper.Hypotenuse(3, 4));
▶ 试一试
TEXT
9
5
📌 尝试 new MathHelper() 会导致编译错误,static 类无法创建实例。

const 与 static readonly

特性 const static readonly
赋值时机 编译时 运行时
值类型 仅内建类型 任意类型
是否可变 不可变 构造函数中赋值后不可变

示例

CSHARP
class Settings
{
    public const int MaxRetry = 3;
    public static readonly DateTime LaunchTime;

    static Settings()
    {
        LaunchTime = DateTime.Now;
    }
}

Console.WriteLine(Settings.MaxRetry);
Console.WriteLine(Settings.LaunchTime);
▶ 试一试
TEXT
3
2026/06/28 10:00:00
⚠️ const 值在编译时嵌入调用方程序集,修改 const 后所有引用方需重新编译。static readonly 在运行时读取,更安全。

扩展方法

扩展方法在不修改原始类型的前提下,为其"添加"方法。定义在 static 类中,第一个参数前加 this 关键字,即可像实例方法一样调用。

示例

CSHARP
static class StringExt
{
    public static bool IsEmpty(this string s) => s.Length == 0;
    public static string Repeat(this string s, int count)
    {
        var sb = new StringBuilder();
        for (int i = 0; i < count; i++) sb.Append(s);
        return sb.ToString();
    }
}

Console.WriteLine("hello".IsEmpty());
Console.WriteLine("ab".Repeat(3));
▶ 试一试
TEXT
False
ababab
💡 扩展方法本质是静态方法调用,编译器将 s.IsEmpty() 转译为 StringExt.IsEmpty(s)。实例方法优先级高于扩展方法。

扩展方法的应用(LINQ 基础)

LINQ 的链式语法正是基于扩展方法实现的。System.Linq.Enumerable 中的 WhereSelectOrderBy 等都是 IEnumerable<T> 的扩展方法。

示例

CSHARP
static class EnumerableExt
{
    public static IEnumerable<T> MyWhere<T>(this IEnumerable<T> source, Func<T, bool> predicate)
    {
        foreach (var item in source)
        {
            if (predicate(item)) yield return item;
        }
    }
}

int[] nums = { 1, 2, 3, 4, 5, 6 };
var even = nums.MyWhere(n => n % 2 == 0);
Console.WriteLine(string.Join(", ", even));
▶ 试一试
TEXT
2, 4, 6
🚀 理解扩展方法原理后,阅读 LINQ 源码将不再困难——它们就是精心设计的扩展方法集合。

partial 类

partial 关键字允许将一个类的定义拆分到多个文件中,编译时合并为一个完整类。常用于自动生成代码与手写代码分离。

示例

CSHARP
partial class User
{
    public string Name { get; set; }
    public User(string name) => Name = name;
}

partial class User
{
    public void Greet() => Console.WriteLine($"你好,{Name}");
}

var u = new User("小明");
u.Greet();
▶ 试一试
TEXT
你好,小明
📌 WinForms、WPF、EF Core 等框架大量使用 partial 类,将设计器生成代码与业务逻辑分开。

partial 方法

partial 方法在 partial 类的一部分中声明,另一部分中可选实现。若未实现,编译器会移除调用处的代码,零开销。C# 9 开始支持无签名限制的 partial 方法。

示例

CSHARP
partial class Order
{
    public int Amount { get; set; }
    partial void OnCreated();

    public Order(int amount)
    {
        Amount = amount;
        OnCreated();
    }
}

partial class Order
{
    partial void OnCreated() => Console.WriteLine("订单已创建");
}

var o = new Order(100);
Console.WriteLine(o.Amount);
▶ 试一试
TEXT
订单已创建
100
💡 若删除第二个 partial 类中的 OnCreated 实现,程序仍可编译通过,且调用处会被编译器自动移除。

❓ 常见问题

Q static 方法能访问实例字段吗?
A 不能。static 方法不与任何实例关联,必须通过对象引用才能访问实例成员。
Q const 和 static readonly 该选哪个?
A 如果是编译期可确定的简单常量用 const;如果是运行时才能确定的值或引用类型,用 static readonly。
Q 扩展方法能访问私有成员吗?
A 不能。扩展方法本质是静态方法,只能访问公共成员。
Q partial 类的所有部分必须在同一程序集吗?
A 是的,partial 类的所有部分必须在同一程序集和同一命名空间中。

📖 小节

📝 作业

  1. 编写一个 static class ArrayHelper,提供 Max(int[] arr)Average(int[] arr) 两个静态方法,并在 Main 中测试
  2. IEnumerable<int> 编写一个扩展方法 MySum,计算整数序列的总和,不使用 LINQ
  3. 创建一个 partial class Logger,在一个部分中定义 partial void OnLog(string message) 声明和 Log(string msg) 方法(内部调用 OnLog),在另一个部分中实现 OnLog 输出到控制台
  4. 定义一个 const 字段和一个 static readonly 字段,编写代码验证 const 在编译时替换而 static readonly 在运行时取值(提示:分别在另一个程序集中引用并观察修改后的行为)
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏