核心明白什么是静态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();
}
}
///
/// 静态类(一 定义)
///
public static class Person
{
// 字段 需要静态 (static 这个变量 类 方法 生成在程序启动之前,消失程序关闭之后,全局唯一存在)
public static string name = "张三";
public static void Speak()
{
MessageBox.Show(name+"讲话");
}
}
}
静态类是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
这是静态类最常见的用途之一,用于封装不依赖于特定实例的通用功能。
示例:自定义数学工具类
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}");
}
}
静态类可用于存储应用程序配置或常量值。
示例:应用程序配置类
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=");
}
}
静态类常用于存放扩展方法(尽管扩展方法本身是实例方法,但它们必须定义在静态类中)。
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
}
}
静态类可用于实现工厂方法模式,创建特定类型的实例。
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");
}
}
特性 | 静态类 | 实例类 |
---|---|---|
实例化 | 不能实例化 | 可以实例化 |
成员 | 只能包含静态成员 | 可以包含实例和静态成员 |
继承 | 不能被继承 | 可以被继承 |
生命周期 | 应用程序域生命周期 | 实例生命周期 |
线程安全 | 通常需要手动实现线程安全 | 每个实例有自己的状态 |
特性 | 静态类 | 单例模式 |
---|---|---|
实例化 | 不能实例化 | 有一个私有实例,通过公共方法访问 |
继承 | 不能被继承 | 可以被继承(通过修改模式) |
延迟初始化 | 不支持 | 支持延迟初始化 |
测试 | 难以模拟(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 = "[email protected]";
Console.WriteLine($"{email} is valid: {StringUtilities.IsValidEmail(email)}"); // 输出: True
}
}
静态类是C#中一个强大但需要谨慎使用的特性。它们非常适合封装与特定类型无关的通用功能、配置和工具方法。通过合理使用静态类,你可以:
然而,也要注意静态类的局限性:
在决定使用静态类之前,评估项目需求和团队工作流程,确保它能真正为你的项目带来价值。对于需要状态或依赖注入的场景,考虑使用单例模式或其他设计模式替代静态类。