C#扩展方法的入门理解
public static class CanGetModelExtension
{public static T GetModel<T>(this ICanGetModel self) where T : class, IModel =>self.GetArchitecture().GetModel<T>();
}
前言:
在学习QFramework时,看底层框架代码注意到这个函数,对于我一个小白来说不明所以,于是GPT了一下,才知道这是一个对ICanGetModel接口的扩展方法,于是想对C#扩展方法进行拆解理解一下,遂笔。
扩展方法的基本语法
public static 返回类型 方法名(this 目标类型 参数名, 其他参数...)
{// 方法实现
}
this
关键字:表示这是一个扩展方法。目标类型
:你要扩展的接口或类(这里是ICanGetModel
)。参数名
:调用该方法的实例(通常命名为self
或source
)。- 任何实现了
ICanGetModel
的类都可以直接调用GetModel<T>()
方法。
使用扩展方法前后代码对比
假设有一个 ICanGetModel
的实现类 GameSystem
:
public class GameSystem : ICanGetModel
{ public IArchitecture GetArchitecture() => GameApp.Interface;
}
(1) 不使用扩展方法
var system = new GameSystem();
var model = system.GetArchitecture().GetModel<PlayerModel>(); // 冗长
(2) 使用扩展方法
var system = new GameSystem();
var model = system.GetModel<PlayerModel>(); // 简洁直观
扩展方法的本质
- 扩展方法只是 语法糖,编译后会变成普通的静态方法调用。
- 它不会修改原始类或接口的实现,只是让调用更便捷。
示例代码Animal使用扩展方法
### 1.定义基类 `Animal` 和派生类
public class Animal
{public string Name { get; set; }public void Speak() => Console.WriteLine($"{Name} makes a sound.");
}public class Dog : Animal
{public void Bark() => Console.WriteLine($"{Name} says: Woof!");
}public class Cat : Animal
{public void Meow() => Console.WriteLine($"{Name} says: Meow!");
}### 2. 定义扩展方法
#### (1) 为 `Animal` 添加扩展方法
public static class AnimalExtensions
{// 扩展方法:让动物重复说话多次public static void RepeatSpeak(this Animal animal, int times){for (int i = 0; i < times; i++){animal.Speak();}}// 扩展方法:检查动物是否是无名氏public static bool IsNameless(this Animal animal){return string.IsNullOrEmpty(animal.Name);}
}#### (2) 为 `Dog` 添加专属扩展方法
public static class DogExtensions
{// 扩展方法:让狗疯狂吠叫public static void CrazyBark(this Dog dog, int barkCount){for (int i = 0; i < barkCount; i++){dog.Bark();}}
}### 3. 使用扩展方法
class Program
{static void Main(){// 创建一个动物和一只狗var genericAnimal = new Animal { Name = "Generic Animal" };var dog = new Dog { Name = "Buddy" };// 调用 Animal 的扩展方法genericAnimal.RepeatSpeak(3); // 输出 3 次 "Generic Animal makes a sound."Console.WriteLine($"Is nameless? {genericAnimal.IsNameless()}"); // 输出 False// 调用 Dog 的扩展方法(继承自 Animal 的也可以调用)dog.RepeatSpeak(2); // 输出 2 次 "Buddy makes a sound."dog.CrazyBark(3); // 输出 3 次 "Buddy says: Woof!"}
}
总结
-
扩展方法的语法:
- 必须定义在 静态类 中(如
AnimalExtensions
)。 - 方法本身必须是 静态方法。
- 第一个参数用
this
修饰,表示要扩展的类型(如this Animal animal
)。
- 必须定义在 静态类 中(如
-
扩展方法的调用:
- 实例可以直接调用扩展方法,就像调用自己的方法一样。
- 例如:
dog.RepeatSpeak(2)
,尽管RepeatSpeak
不是Dog
的成员方法。
-
扩展方法的限制:
- 不能访问类的私有成员(因为本质是静态方法)。
- 如果类本身有同名方法,实例方法优先级更高。
-
扩展方法的作用:
- 增强现有类:无需修改原始类,就能添加新功能。
- 链式调用:例如 LINQ 的
Where().Select()
。