核心明白什么是静态static 产生在程序启动之前,消失程序结束之后,全局存在 不需要实例化,就可以使用
13C#之静态类
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace C_之静态类
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
- private void button1_Click(object sender, EventArgs e)
- {
- // 使用(不需要实例化)
- Person.Speak();
- }
- }
- /// <summary>
- /// 静态类(一 定义)
- /// </summary>
- public static class Person
- {
- // 字段 需要静态 (static 这个变量 类 方法 生成在程序启动之前,消失程序关闭之后,全局唯一存在)
- public static string name = "张三";
- public static void Speak()
- {
- MessageBox.Show(name+"讲话");
- }
- }
- }
复制代码
C# 静态类(Static Classes)完全指南
静态类是C#中一种特殊的类类型,它提供了一种将工具方法、常量和其他共享数据组织在一起的方式,而无需实例化对象。本文将深入探讨静态类的各个方面,包括其定义、特性、使用场景、最佳实践以及与相关概念的对比。
什么是静态类?
静态类是使用static关键字修饰的类,它不能被实例化,只能通过类名直接访问其成员。静态类通常用于封装与特定类型无关但需要全局访问的功能。
基本语法 - public static class MathUtilities
- {
- // 静态字段
- public const double Pi = 3.141592653589793;
-
- // 静态方法
- public static double CalculateCircleArea(double radius)
- {
- return Pi * radius * radius;
- }
-
- // 静态属性
- public static string Version => "1.0.0";
- }
复制代码
静态类的核心特性
- 不能实例化:静态类没有构造函数(也不能有实例构造函数)
- 自动为密封和抽象:静态类隐式为sealed(不能被继承)和abstract(不能被实例化)
- 只能包含静态成员:所有字段、方法、属性等都必须声明为static
- 不能包含实例成员:尝试添加非静态成员会导致编译错误
- 编译时常量:静态类中的常量会在编译时解析
静态类的常见用途
1. 数学和实用工具类
这是静态类最常见的用途之一,用于封装不依赖于特定实例的通用功能。
示例:自定义数学工具类 - public static class AdvancedMath
- {
- // 常量
- public const double E = 2.718281828459045;
-
- // 静态方法
- public static double Factorial(int n)
- {
- if (n < 0) throw new ArgumentException("n must be non-negative");
- if (n == 0) return 1;
-
- double result = 1;
- for (int i = 1; i <= n; i++)
- {
- result *= i;
- }
- return result;
- }
-
- public static double LogBase(double value, double baseValue)
- {
- if (value <= 0 || baseValue <= 0 || baseValue == 1)
- throw new ArgumentException("Invalid arguments for logarithm");
-
- return Math.Log(value) / Math.Log(baseValue);
- }
-
- // 静态属性
- public static int MaxIntegerValue => int.MaxValue;
- }
- // 使用示例
- class Program
- {
- static void Main()
- {
- Console.WriteLine($"5! = {AdvancedMath.Factorial(5)}");
- Console.WriteLine($"Log2(8) = {AdvancedMath.LogBase(8, 2)}");
- Console.WriteLine($"Max int value: {AdvancedMath.MaxIntegerValue}");
- }
- }
复制代码
2. 配置和常量存储
静态类可用于存储应用程序配置或常量值。
示例:应用程序配置类 - public static class AppConfig
- {
- // 配置常量
- public static string DatabaseConnectionString =>
- "Server=myServer;Database=myDB;Trusted_Connection=True;";
-
- public static int MaxRetryAttempts => 3;
-
- public static TimeSpan Timeout => TimeSpan.FromSeconds(30);
-
- // 静态方法(用于验证配置)
- public static bool IsValidConnectionString(string connectionString)
- {
- return !string.IsNullOrWhiteSpace(connectionString) &&
- connectionString.Contains("Server=") &&
- connectionString.Contains("Database=");
- }
- }
复制代码
3. 扩展方法容器
静态类常用于存放扩展方法(尽管扩展方法本身是实例方法,但它们必须定义在静态类中)。 - public static class StringExtensions
- {
- public static bool IsNullOrEmpty(this string str)
- {
- return string.IsNullOrEmpty(str);
- }
-
- public static string Reverse(this string str)
- {
- if (str == null) throw new ArgumentNullException(nameof(str));
-
- char[] charArray = str.ToCharArray();
- Array.Reverse(charArray);
- return new string(charArray);
- }
-
- public static string Truncate(this string str, int maxLength)
- {
- if (str == null) throw new ArgumentNullException(nameof(str));
- if (maxLength < 0) throw new ArgumentOutOfRangeException(nameof(maxLength));
-
- return str.Length <= maxLength ? str : str.Substring(0, maxLength);
- }
- }
- // 使用示例
- class Program
- {
- static void Main()
- {
- string test = "Hello, World!";
- Console.WriteLine(test.Reverse()); // 输出: !dlroW ,olleH
- Console.WriteLine(test.Truncate(5)); // 输出: Hello
- Console.WriteLine("".IsNullOrEmpty()); // 输出: True
- }
- }
复制代码
4. 工厂方法模式
静态类可用于实现工厂方法模式,创建特定类型的实例。 - public static class LoggerFactory
- {
- public static ILogger CreateFileLogger(string filePath)
- {
- return new FileLogger(filePath);
- }
-
- public static ILogger CreateConsoleLogger()
- {
- return new ConsoleLogger();
- }
-
- public static ILogger CreateNullLogger()
- {
- return new NullLogger();
- }
- }
- // 接口定义
- public interface ILogger
- {
- void Log(string message);
- }
- // 具体实现(简化版)
- class FileLogger : ILogger { /*...*/ }
- class ConsoleLogger : ILogger { /*...*/ }
- class NullLogger : ILogger { /*...*/ }
- // 使用示例
- class Program
- {
- static void Main()
- {
- ILogger logger = LoggerFactory.CreateFileLogger("app.log");
- logger.Log("Application started");
- }
- }
复制代码
静态类与相关概念的对比
1. 静态类 vs 实例类
| 特性 | 静态类 | 实例类 |
|---|
| 实例化 | 不能实例化 | 可以实例化 | | 成员 | 只能包含静态成员 | 可以包含实例和静态成员 | | 继承 | 不能被继承 | 可以被继承 | | 生命周期 | 应用程序域生命周期 | 实例生命周期 | | 线程安全 | 通常需要手动实现线程安全 | 每个实例有自己的状态 |
2. 静态类 vs 单例模式
| 特性 | 静态类 | 单例模式 |
|---|
| 实例化 | 不能实例化 | 有一个私有实例,通过公共方法访问 | | 继承 | 不能被继承 | 可以被继承(通过修改模式) | | 延迟初始化 | 不支持 | 支持延迟初始化 | | 测试 | 难以模拟(mock) | 相对容易模拟 | | 多态性 | 不支持 | 支持 |
静态类的最佳实践
-
命名规范:为静态类使用描述性名称,通常以"Utility"、“Helper”、"Factory"等后缀结尾 -
线程安全:如果静态类包含可变状态,确保实现线程安全 - public static class ThreadSafeCounter
- {
- private static int _count = 0;
- private static readonly object _lock = new object();
-
- public static int Increment()
- {
- lock (_lock)
- {
- return ++_count;
- }
- }
-
- public static int GetCount()
- {
- lock (_lock)
- {
- return _count;
- }
- }
- }
复制代码 -
避免过度使用:静态类会创建全局状态,可能导致代码难以测试和维护 -
单一职责原则:每个静态类应该只负责一个特定的功能领域 -
文档注释:为静态类和方法添加清晰的XML文档注释 -
常量命名:常量使用全大写命名,单词间用下划线分隔 - public static class AppConstants
- {
- public const int MAX_USERS = 100;
- public const string DEFAULT_THEME = "Light";
- }
复制代码
静态类的局限性
-
不能实现接口:静态类不能实现接口,因为接口需要实例来调用 -
不能作为基类:静态类不能作为其他类的基类 -
依赖注入困难:静态类难以与依赖注入框架集成 -
测试挑战:静态类中的方法难以模拟(mock),影响单元测试
完整示例:综合应用
下面是一个综合使用静态类的完整示例,展示了静态类在配置管理、实用工具方法和扩展方法中的应用: - // 配置静态类
- public static class AppSettings
- {
- public static string ApiBaseUrl => "https://api.example.com/v1";
- public static int MaxConcurrentRequests => 10;
- public static TimeSpan RequestTimeout => TimeSpan.FromSeconds(30);
-
- public static void Validate()
- {
- if (string.IsNullOrWhiteSpace(ApiBaseUrl))
- throw new InvalidOperationException("API base URL is not configured");
-
- if (MaxConcurrentRequests <= 0)
- throw new InvalidOperationException("Max concurrent requests must be positive");
- }
- }
- // 实用工具静态类
- public static class StringUtilities
- {
- public static string FormatAsUrl(this string input)
- {
- if (string.IsNullOrWhiteSpace(input))
- return string.Empty;
-
- return input
- .Trim()
- .ToLowerInvariant()
- .Replace(" ", "-")
- .Replace("__", "-") // 清理多余的下划线
- .Replace("__", "-")
- .Replace("__", "-");
- }
-
- public static bool IsValidEmail(string email)
- {
- if (string.IsNullOrWhiteSpace(email))
- return false;
-
- try
- {
- var addr = new System.Net.Mail.MailAddress(email);
- return addr.Address == email;
- }
- catch
- {
- return false;
- }
- }
- }
- // 扩展方法静态类
- public static class DateTimeExtensions
- {
- public static string ToRelativeTime(this DateTime dateTime)
- {
- var timeSpan = DateTime.Now - dateTime;
-
- if (timeSpan <= TimeSpan.FromSeconds(60))
- return $"{timeSpan.Seconds} seconds ago";
- if (timeSpan <= TimeSpan.FromMinutes(60))
- return $"{timeSpan.Minutes} minutes ago";
- if (timeSpan <= TimeSpan.FromHours(24))
- return $"{timeSpan.Hours} hours ago";
- if (timeSpan <= TimeSpan.FromDays(30))
- return $"{timeSpan.Days} days ago";
-
- return dateTime.ToString("yyyy-MM-dd");
- }
- }
- // 使用示例
- class Program
- {
- static void Main()
- {
- // 验证配置
- AppSettings.Validate();
-
- // 使用字符串工具
- string rawUrl = " My Page Title ";
- string formattedUrl = rawUrl.FormatAsUrl();
- Console.WriteLine($"Formatted URL: {formattedUrl}"); // 输出: my-page-title
-
- // 使用扩展方法
- DateTime pastDate = DateTime.Now.AddDays(-5);
- Console.WriteLine($"5 days ago: {pastDate.ToRelativeTime()}"); // 输出: 5 days ago
-
- // 验证邮箱
- string email = "test@example.com";
- Console.WriteLine($"{email} is valid: {StringUtilities.IsValidEmail(email)}"); // 输出: True
- }
- }
复制代码
结论
静态类是C#中一个强大但需要谨慎使用的特性。它们非常适合封装与特定类型无关的通用功能、配置和工具方法。通过合理使用静态类,你可以:
- 提高代码的可读性和可维护性,将相关功能组织在一起
- 提供全局可访问的工具方法,而无需实例化对象
- 创建不可变的配置容器
- 实现工厂方法模式
然而,也要注意静态类的局限性:
- 它们创建全局状态,可能导致代码难以测试和维护
- 不能实现接口或多态性
- 难以与依赖注入框架集成
在决定使用静态类之前,评估项目需求和团队工作流程,确保它能真正为你的项目带来价值。对于需要状态或依赖注入的场景,考虑使用单例模式或其他设计模式替代静态类。 |