C# 封装动作<;T>;和Func<;T>;?

C# 封装动作<;T>;和Func<;T>;?,c#,parameters,action,overloading,func,C#,Parameters,Action,Overloading,Func,我正在尝试为某种IExecutable接口进行设计。我将不深入讨论细节,但重点是我有几个操作需要从基类执行。它们可能采用不同的参数(没什么大不了的),并且可能/可能不返回值 到目前为止,这是我的设计: public abstract class ActionBase { // ... snip ... } public abstract class ActionWithResultBase<T>: ActionBase { public abstract T Exe

我正在尝试为某种IExecutable接口进行设计。我将不深入讨论细节,但重点是我有几个操作需要从基类执行。它们可能采用不同的参数(没什么大不了的),并且可能/可能不返回值

到目前为止,这是我的设计:

public abstract class ActionBase
{
    // ... snip ...
}

public abstract class ActionWithResultBase<T>: ActionBase
{
    public abstract T Execute();
}

public abstract class ActionWithoutResultBase: ActionBase
{
    public abstract void Execute();
}

您知道可以忽略方法的返回值,对吗?你不必使用它。

如果你想要一个轻量级的解决方案,那么最简单的选择就是编写两个具体的类。一个包含类型为
Action
的属性,另一个包含类型为
Func
的属性:

要创建
Func
值,您将编写:

Func<Unit> f = () => { /* ... */ return Unit.Value; }
Func f=()=>{/*…*/返回单位.Value;}

简单点怎么样:

public class ActionExecuter
{
    private MulticastDelegate del;
    public ActionExecuter(MulticastDelegate del)
    {
        this.del = del;
    }

    public object Execute(params object[] p)
    {
        return del.DynamicInvoke(p);
    }
}

下面的接口应该可以做到这一点——它实际上是在复制可为null的模式

public interface IActionBase
{
       bool HasResult { get; }
       void Execute() { }
       object Result { get; }
}

public interface IActionBase<T> : IActionBase
{
       new T Result { get; }
}

public sealed class ActionWithReturnValue<T> : IActionBase<T>
{
       public ActionWithReturnValue(Func<T> action) {  _action = action; }
       private Func<T> _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() { //... }
}
公共接口IActionBase
{
bool HasResult{get;}
void Execute(){}
对象结果{get;}
}
公共接口IActionBase:IActionBase
{
新的T结果{get;}
}
返回值为:IActionBase的公共密封类操作
{
public ActionWithReturnValue(Func action){u action=action;}
私人职能行动;
public bool HasResult{get;private set;}
对象IActionBase.Result{get{返回此.Result;}}
公共T结果{get;私有集;}
public void Execute()
{
HasResult=false;
结果=默认值(T);
尝试
{ 
结果=_action();
HasResult=true;
}
抓住
{
HasResult=false;
结果=默认值(T);
}  
}
}
未返回值的公共密封类操作:IActionBase
{
public bool HasResult{get{return false;}}
对象IActionBase.Result{get{return null;}}
public void Execute(){/…}
}

是的,你说的没错,但我认为这不是设计上的明智之举。另外,有人建议我对那些不返回的东西总是返回bool,这仅仅表明手术是成功的,但我也认为这是不正确的。如果操作不应该返回值,为什么要强制它?@Alpha-我同意你的观点,如果操作不能自然返回值,那么它就不应该返回。返回“true”是不对的,因为通常不应该返回“false”,而应该抛出异常。然而,我仍然不理解你的设计目标——你的目标似乎是基于语法上的糖分,我看不出你在完成什么,你不能仅仅让动作和函数来解决。我认为您需要解释它们的问题是什么?作为澄清:我的目标是在ActionBase中执行抽象,避免创建ActionWithResultBase和ActionWithoutResultBase。还考虑了类似的问题,但我的问题是在编译时不知道返回的是哪种类型。我总是可以让ActionExecuter和Execute返回T,但我不需要返回任何东西。谢谢。我知道我等了很久才给你打分,但我真的很想看看是否有人想出了解决办法。即使您的方法不能完全解决问题,它确实是一个很好的答案,并且显示了一个很好的解决方法,可以解决这个问题。
public class Unit {
  public static Unit Value { get { return null; } }
}
Func<Unit> f = () => { /* ... */ return Unit.Value; }
public class ActionExecuter
{
    private MulticastDelegate del;
    public ActionExecuter(MulticastDelegate del)
    {
        this.del = del;
    }

    public object Execute(params object[] p)
    {
        return del.DynamicInvoke(p);
    }
}
public interface IActionBase
{
       bool HasResult { get; }
       void Execute() { }
       object Result { get; }
}

public interface IActionBase<T> : IActionBase
{
       new T Result { get; }
}

public sealed class ActionWithReturnValue<T> : IActionBase<T>
{
       public ActionWithReturnValue(Func<T> action) {  _action = action; }
       private Func<T> _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() { //... }
}