扩展方法 #
一、扩展方法概述 #
1.1 什么是扩展方法 #
扩展方法允许向现有类型添加方法,而无需修改原始类型。
1.2 扩展方法特点 #
- 静态类中定义
- 第一个参数用this修饰
- 编译时绑定
- 可扩展任何类型
二、定义扩展方法 #
2.1 基本语法 #
csharp
public static class StringExtensions
{
public static string Reverse(this string str)
{
var chars = str.ToCharArray();
Array.Reverse(chars);
return new string(chars);
}
}
string text = "Hello";
string reversed = text.Reverse();
2.2 扩展方法参数 #
csharp
public static class StringExtensions
{
public static string Repeat(this string str, int count)
{
return string.Concat(Enumerable.Repeat(str, count));
}
}
string text = "Hi";
string repeated = text.Repeat(3);
2.3 扩展集合类型 #
csharp
public static class CollectionExtensions
{
public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
{
foreach (var item in collection)
{
action(item);
}
}
public static bool IsEmpty<T>(this IEnumerable<T> collection)
{
return !collection.Any();
}
}
var numbers = new List<int> { 1, 2, 3 };
numbers.ForEach(n => Console.WriteLine(n));
var empty = new List<int>();
bool isEmpty = empty.IsEmpty();
三、常用扩展方法 #
3.1 字符串扩展 #
csharp
public static class StringExtensions
{
public static bool IsNullOrEmpty(this string? str)
{
return string.IsNullOrEmpty(str);
}
public static bool IsNullOrWhiteSpace(this string? str)
{
return string.IsNullOrWhiteSpace(str);
}
public static string Truncate(this string str, int maxLength)
{
if (str.Length <= maxLength) return str;
return str.Substring(0, maxLength) + "...";
}
public static string ToTitleCase(this string str)
{
return System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
}
}
string? name = null;
bool empty = name.IsNullOrEmpty();
string longText = "这是一段很长的文本内容";
string truncated = longText.Truncate(10);
3.2 数值扩展 #
csharp
public static class NumericExtensions
{
public static bool IsEven(this int number)
{
return number % 2 == 0;
}
public static bool IsOdd(this int number)
{
return number % 2 != 0;
}
public static bool IsBetween(this int number, int min, int max)
{
return number >= min && number <= max;
}
public static string ToFileSize(this long bytes)
{
string[] sizes = { "B", "KB", "MB", "GB", "TB" };
int order = 0;
double size = bytes;
while (size >= 1024 && order < sizes.Length - 1)
{
order++;
size /= 1024;
}
return $"{size:0.##} {sizes[order]}";
}
}
int num = 10;
bool even = num.IsEven();
bool inRange = num.IsBetween(1, 100);
long fileSize = 1024 * 1024;
string size = fileSize.ToFileSize();
3.3 日期扩展 #
csharp
public static class DateTimeExtensions
{
public static bool IsWeekend(this DateTime date)
{
return date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday;
}
public static bool IsToday(this DateTime date)
{
return date.Date == DateTime.Today;
}
public static int Age(this DateTime birthDate)
{
var today = DateTime.Today;
var age = today.Year - birthDate.Year;
if (birthDate.Date > today.AddYears(-age)) age--;
return age;
}
public static DateTime StartOfWeek(this DateTime date, DayOfWeek startOfWeek = DayOfWeek.Monday)
{
int diff = (7 + (date.DayOfWeek - startOfWeek)) % 7;
return date.AddDays(-diff).Date;
}
}
DateTime date = DateTime.Now;
bool isWeekend = date.IsWeekend();
DateTime birthDate = new DateTime(1990, 5, 15);
int age = birthDate.Age();
四、扩展接口 #
4.1 扩展IEnumerable #
csharp
public static class EnumerableExtensions
{
public static string JoinToString<T>(this IEnumerable<T> collection, string separator = ", ")
{
return string.Join(separator, collection);
}
public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> collection, Func<T, TKey> keySelector)
{
return collection.GroupBy(keySelector).Select(g => g.First());
}
public static void Apply<T>(this IEnumerable<T> collection, Action<T> action)
{
foreach (var item in collection)
{
action(item);
}
}
}
var numbers = new[] { 1, 2, 3, 4, 5 };
string joined = numbers.JoinToString("-");
var people = new[] { new { Name = "张三", Age = 25 }, new { Name = "李四", Age = 25 } };
var distinct = people.DistinctBy(p => p.Age);
五、扩展方法优先级 #
5.1 解析顺序 #
- 实例方法优先
- 当前命名空间的扩展方法
- 外部命名空间的扩展方法
csharp
public class MyClass
{
public void DoSomething() { }
}
public static class MyClassExtensions
{
public static void DoSomething(this MyClass obj) { }
}
var obj = new MyClass();
obj.DoSomething();
六、最佳实践 #
6.1 命名规范 #
csharp
public static class StringExtensions { }
public static class DateTimeExtensions { }
public static class EnumerableExtensions { }
6.2 适度使用 #
csharp
public static class StringExtensions
{
public static string Reverse(this string str) { }
public static string Truncate(this string str, int maxLength) { }
}
public static class StringParserExtensions
{
public static bool TryParseInt(this string str, out int result) { }
}
七、总结 #
扩展方法要点:
| 要点 | 说明 |
|---|---|
| 静态类 | 必须在静态类中 |
| this关键字 | 第一个参数 |
| 命名空间 | 需要引入 |
| 优先级 | 实例方法优先 |
下一步,让我们学习LINQ!
最后更新:2026-03-26