C# .NET中如何将带双函数参数的Lambda作为类构造方法参数?
在C# .NET中实现带Lambda逻辑的构造函数参数
你之前尝试用Action没成功,核心问题是普通Action系列委托没法满足你需要的“接受两个函数作为参数”的逻辑定义。咱们一步步来解决这个问题:
1. 明确你需要的委托类型
你的Lambda表达式(func1, func2) => { ... }是接受两个函数参数(func1和func2),并且这两个函数本身又接受一个cool类型的参数(假设cool是bool,你可以根据实际类型调整)。
针对这个场景,你可以用嵌套的Action委托,或者自定义一个可读性更强的委托类型。
方案一:使用嵌套Action委托
我们直接用Action<Action<T>, Action<T>>作为构造函数的参数类型,其中T是cool的类型(比如bool)。
先定义你的SomeClass类:
public class SomeClass { // 存储传入的逻辑 private readonly Action<Action<bool>, Action<bool>> _logic; // 把cool变量传入类中存储,避免闭包陷阱 private readonly bool _cool; // 构造函数接受逻辑参数和cool变量 public SomeClass(bool cool, Action<Action<bool>, Action<bool>> executionLogic) { _cool = cool; _logic = executionLogic; } // 提供方法触发逻辑执行 public void RunLogic() { // 定义实际业务逻辑的func1和func2(示例代码,可替换为你的业务逻辑) Action<bool> func1 = c => Console.WriteLine($"执行Func1,参数:{c}"); Action<bool> func2 = c => Console.WriteLine($"执行Func2,参数:{c}"); // 调用传入的Lambda逻辑 _logic(func1, func2); } }
然后使用这个类:
bool coolFlag = true; // 你的cool变量 var someClass = new SomeClass(coolFlag, (func1, func2) => { if (coolFlag) { func1(coolFlag); } else { func2(coolFlag); } }); // 触发逻辑执行 someClass.RunLogic();
方案二:自定义委托类型(可读性更强)
如果你觉得嵌套Action的写法不够直观,可以自定义一个委托类型:
// 自定义委托:接受两个Action<T>类型的参数 public delegate void ExecutionLogic<T>(Action<T> func1, Action<T> func2);
然后修改SomeClass的构造函数参数类型:
public class SomeClass { private readonly ExecutionLogic<bool> _logic; private readonly bool _cool; public SomeClass(bool cool, ExecutionLogic<bool> executionLogic) { _cool = cool; _logic = executionLogic; } public void RunLogic() { Action<bool> func1 = c => Console.WriteLine($"执行Func1,参数:{c}"); Action<bool> func2 = c => Console.WriteLine($"执行Func2,参数:{c}"); _logic(func1, func2); } }
使用方式和方案一完全一致,只是委托类型的名字更清晰。
2. 适配不同类型的cool参数
如果你的cool不是bool,而是其他类型(比如自定义类、字符串等),只需要把所有的Action<bool>改成对应的Action<T>,甚至可以把SomeClass改成泛型类:
public class SomeClass<T> { private readonly ExecutionLogic<T> _logic; private readonly T _cool; public SomeClass(T cool, ExecutionLogic<T> executionLogic) { _cool = cool; _logic = executionLogic; } public void RunLogic() { Action<T> func1 = c => Console.WriteLine($"执行Func1,参数:{c}"); Action<T> func2 = c => Console.WriteLine($"执行Func2,参数:{c}"); _logic(func1, func2); } } // 使用示例(cool是字符串) var coolText = "测试文本"; var someClass = new SomeClass<string>(coolText, (func1, func2) => { if (!string.IsNullOrEmpty(coolText)) { func1(coolText); } else { func2(coolText); } });
3. 注意闭包陷阱
如果你在Lambda中直接捕获外部变量(比如没把cool传入类中,而是直接在Lambda里用外部的cool),要注意变量后续修改会影响Lambda的执行结果。比如:
bool coolFlag = true; var someClass = new SomeClass((func1, func2) => { if (coolFlag) func1(coolFlag); else func2(coolFlag); }); coolFlag = false; // 这里修改会导致后续调用RunLogic时执行func2 someClass.RunLogic();
如果想避免这个问题,建议把cool变量通过构造函数传入类中存储,就像前面示例里那样。
内容的提问来源于stack exchange,提问作者Leon Marzahn
相关产品推荐
相关产品推荐

