封装Action 和Func ?
我正在尝试为某种IExecutable接口进行设计。 我不会详细介绍,但重点是我有几个需要从基类执行的动作。 它们可能采用不同的参数(没什么大不了的),它们可能/可能不会返回值。
到目前为止,这是我的设计:
public abstract class ActionBase { // ... snip ... } public abstract class ActionWithResultBase: ActionBase { public abstract T Execute(); } public abstract class ActionWithoutResultBase: ActionBase { public abstract void Execute(); }
到目前为止,我的每个具体动作都需要来自ActionWithResultBase或ActionWithoutResult基础的孩子,但我真的不喜欢这样。 如果我可以将Execute的定义移动到ActionBase,考虑到具体类可能会或可能不会返回值,我将实现我的目标。
有人告诉我这可以通过使用Func和Action来完成,我完全同意,但我找不到一种方法将它放到一个单独的类中,以便调用者知道该操作是否将返回一个值或不。
简介:我想做的事情如下:
// Action1.Execute() returns something. var a = new Action1(); var result = a.Execute(); // Action2.Execute() returns nothing. var b = new Action2(); b.Execute();
如果你想要一个轻量级的解决方案,那么最简单的选择就是编写两个具体的类。 一个将包含Action
类型的属性,另一个包含Func
类型的属性:
public class ActionWithResult : ActionBase { public Func Action { get; set; } } public class ActionWithoutResult : ActionBase { public Action Action { get; set; } }
然后你可以像这样构造两种类型:
var a1 = new ActionWithResult { CanExecute = true, Action = () => { Console.WriteLine("hello!"); return 10; } }
如果您不想使Action
属性读/写,那么您可以将操作委托作为参数传递给构造函数,并使该属性为readonly。
C#需要两个不同的委托来表示函数和动作这一事实非常烦人。 人们使用的一种解决方法是定义一个表示“无返回值”的类型Unit
,并使用它而不是void
。 然后你的类型只是Func
,你可以使用Func
而不是Action
。 Unit
类型可能如下所示:
public class Unit { public static Unit Value { get { return null; } } }
要创建Func
值,您将写入:
Func f = () => { /* ... */ return Unit.Value; }
以下接口应该可以解决这个问题 – 它本质上是复制Nullable模式
public interface IActionBase { bool HasResult { get; } void Execute() { } object Result { get; } } public interface IActionBase : IActionBase { new T Result { get; } } public sealed class ActionWithReturnValue : IActionBase { public ActionWithReturnValue(Func action) { _action = action; } private Func _action; public bool HasResult { get; private set; } object IActionBase.Result { get { return this.Result; } } public T Result { get; private set; } public void Execute() { HasResult = false; Result = default(T); try { Result = _action(); HasResult = true; } catch { HasResult = false; Result = default(T); } } } public sealed class ActionWithoutReturnValue : IActionBase { public bool HasResult { get { return false; } } object IActionBase.Result { get { return null; } } public void Execute() { //... } }
你知道你可以忽略方法的返回值吗? 你不必使用它。
简单的事情:
上述就是C#学习教程:封装Action 和Func ?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
public class ActionExecuter { private MulticastDelegate del; public ActionExecuter(MulticastDelegate del) { this.del = del; } public object Execute(params object[] p) { return del.DynamicInvoke(p); } }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/956959.html