1.扩展方法:
扩展方法允许向现有类型 “添加” 方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但可以像实例方法一样进行调用。
使用场景:
1.当无法修改某个类的源代码,但又希望为该类添加一些实用方法时,扩展方法就非常有用。
2.为第三方库中的类型添加额外的功能。
实现:
1.基础实现:
public class ExtensionTest : MonoBehaviour
{
void Start()
{
MyClass obj = new MyClass(5);
// 可以像调用实例方法一样调用扩展方法
int result = obj.DoubleValue();
Debug.Log($"Double value: {result}");
}
}
// 定义一个简单的类
public class MyClass
{
public int Value { get; set; }
public MyClass(int value)
{
Value = value;
}
}
// 扩展方法必须定义在静态类中
public static class MyClassExtensions
{
// 扩展方法必须是静态方法,且第一个参数使用 this 关键字指定要扩展的类型
public static int DoubleValue(this MyClass myClass)
{
return myClass.Value * 2;
}
}
结果:
2.链式扩展:
public class ExtensionTest : MonoBehaviour
{
void Start()
{
Person person = new Person("John", 25);
// 链式调用扩展方法
person.SetName("Alice").SetAge(30).PrintInfo();
}
}
// 定义一个简单的类
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
public void PrintInfo()
{
Debug.Log($"Name: {Name}, Age: {Age}");
}
}
// 扩展方法类
public static class PersonExtensions
{
// 扩展方法:设置姓名
public static Person SetName(this Person person, string name)
{
person.Name = name;
return person;
}
// 扩展方法:设置年龄
public static Person SetAge(this Person person, int age)
{
person.Age = age;
return person;
}
}
结果:
2.钩子机制:
在 C# 中,钩子通常指的是在程序执行过程中预留的一些 “可插入点”,允许开发者在特定的时机插入自定义的逻辑。常见的实现方式有事件(Event)、抽象方法、委托等
使用场景:
1.当你需要在某个操作的前后执行自定义逻辑时,可以使用钩子。
2.实现插件化架构,允许开发者在系统的某些关键位置插入自定义的功能。
实现:
1.虚方法钩子:基类定义一个虚方法,该方法可以包含默认的实现逻辑,也可以为空。派生类重写这个虚方法,在其中添加自定义的逻辑。基类在执行某个算法时,会调用这个虚方法,这样派生类就可以在这个 “钩子点” 上插入自己的代码。
public class HookTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
// 创建魔法师角色
GameCharacter mage = new Mage();
mage.Attack();
Console.WriteLine();
// 创建战士角色
GameCharacter warrior = new Warrior();
warrior.Attack();
}
}
public class HookTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
// 创建魔法师角色
GameCharacter mage = new Mage();
mage.Attack();
Console.WriteLine();
// 创建战士角色
GameCharacter warrior = new Warrior();
warrior.Attack();
}
}
// 基类:游戏角色
public class GameCharacter
{
// 虚方法,作为钩子
public virtual void SpecialAbility()
{
Debug.Log("No special ability.");
}
// 角色的攻击方法,会调用钩子方法
public void Attack()
{
Debug.Log("Character attacks!");
SpecialAbility();
}
}
// 派生类:魔法师
public class Mage : GameCharacter
{
// 重写虚方法,添加自定义逻辑
public override void SpecialAbility()
{
Debug.Log("Mage casts a fireball!");
}
}
// 派生类:战士
public class Warrior : GameCharacter
{
// 重写虚方法,添加自定义逻辑
public override void SpecialAbility()
{
Debug.Log("Warrior uses a powerful shield bash!");
}
}
结果:
2.事件钩子:
public class HookTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
MyProcessor processor = new MyProcessor();
// 订阅事件,插入自定义逻辑
processor.BeforeProcess += (sender, e) =>
{
Debug.Log("Before process: Custom logic executed.");
};
processor.AfterProcess += (sender, e) =>
{
Debug.Log("After process: Custom logic executed.");
};
processor.Process();
}
}
// 定义一个包含钩子的类
public class MyProcessor
{
// 定义事件,作为钩子
public event EventHandler BeforeProcess;
public event EventHandler AfterProcess;
public void Process()
{
// 在处理前触发事件
BeforeProcess?.Invoke(this, EventArgs.Empty);
Debug.Log("Processing...");
// 在处理后触发事件
AfterProcess?.Invoke(this, EventArgs.Empty);
}
}
结果:
总结:
通过合理使用扩展方法和钩子方法,可以在保持外观模式简洁性的同时,提供强大的扩展能力。
1.扩展方法适合添加横向功能(如日志、监控)。
2.虚方法钩子适合调整核心流程。
3.事件机制适合实现观察者模式的松散耦合。
4.优先选择组合而非多层继承。