C#中扩展方法和钩子机制使用
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 updatevoid 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 updatevoid 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 updatevoid 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.优先选择组合而非多层继承。