C#之静态类

核心明白什么是静态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 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";
}

静态类的核心特性

  1. 不能实例化:静态类没有构造函数(也不能有实例构造函数)
  2. 自动为密封和抽象:静态类隐式为sealed(不能被继承)和abstract(不能被实例化)
  3. 只能包含静态成员:所有字段、方法、属性等都必须声明为static
  4. 不能包含实例成员:尝试添加非静态成员会导致编译错误
  5. 编译时常量:静态类中的常量会在编译时解析

静态类的常见用途

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) 相对容易模拟
多态性 不支持 支持

静态类的最佳实践

  1. 命名规范:为静态类使用描述性名称,通常以"Utility"、“Helper”、"Factory"等后缀结尾

  2. 线程安全:如果静态类包含可变状态,确保实现线程安全

    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;
            }
        }
    }
    
  3. 避免过度使用:静态类会创建全局状态,可能导致代码难以测试和维护

  4. 单一职责原则:每个静态类应该只负责一个特定的功能领域

  5. 文档注释:为静态类和方法添加清晰的XML文档注释

  6. 常量命名:常量使用全大写命名,单词间用下划线分隔

    public static class AppConstants
    {
        public const int MAX_USERS = 100;
        public const string DEFAULT_THEME = "Light";
    }
    

静态类的局限性

  1. 不能实现接口:静态类不能实现接口,因为接口需要实例来调用

  2. 不能作为基类:静态类不能作为其他类的基类

  3. 依赖注入困难:静态类难以与依赖注入框架集成

  4. 测试挑战:静态类中的方法难以模拟(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#中一个强大但需要谨慎使用的特性。它们非常适合封装与特定类型无关的通用功能、配置和工具方法。通过合理使用静态类,你可以:

  1. 提高代码的可读性和可维护性,将相关功能组织在一起
  2. 提供全局可访问的工具方法,而无需实例化对象
  3. 创建不可变的配置容器
  4. 实现工厂方法模式

然而,也要注意静态类的局限性:

  • 它们创建全局状态,可能导致代码难以测试和维护
  • 不能实现接口或多态性
  • 难以与依赖注入框架集成

在决定使用静态类之前,评估项目需求和团队工作流程,确保它能真正为你的项目带来价值。对于需要状态或依赖注入的场景,考虑使用单例模式或其他设计模式替代静态类。

你可能感兴趣的:(c#,开发语言)