通常用类封装动作/功能?

时间:2011-12-21 11:05:27

标签: c# .net generics

我想一般性地提供动作/方法的封装。我认为这应该可以在C#中实现,但是我无法生成它以便编译...

以下简要说明我想要的内容。这可能是某种方式,也许是通过推广这个类?

要求是:

  • 我想执行函数/动作(参见方法类型)并在发生错误时“执行某些操作”
  • 我想返回函数的值如果该方法是一个函数(否则返回void
  • 如果函数的返回类型为boolean且值为false,我想“做某事”。

    public class Encapsulator {
        private Action _action;
        private Func<T> _function;
        private MethodType _type; //Action || Function
    
        public Encapsulator(Action action) {
            this._action = action;
            this._type = MethodType.Action;
        }
        public Encapsulator(Func<T> func) { //This is not accepted
            this._function = func;
            this._type = MethodType.Function;        
        }
    
        public void Execute() {
            try {
                this._action();
            }
            catch(Exception ex) {
                //do something
                throw;
            }
        }
    
        public T Execute<T>() {
            try {
                var r = this._function();
    
                if(typeof(r) == bool) {
                    if(!r)
                      //do something
                }
    
                return r;
    
            } catch(Exception ex) {
                //do something
                throw;
            }
        }
    }
    

2 个答案:

答案 0 :(得分:1)

你的第二个构造函数将无法编译,因为它们没有应用于更高级别的类型的泛型:

public Encapsulator<T>
{  
    public Encapsulator(Func<T> func)
    { 
        this._function = func;
        this._type = MethodType.Function;  
    }      
}

本质上,我们需要指定那些在定义中“可用”的东西,而不仅仅是在方法的参数中引入新东西。因此,举例来说,如果您尝试添加特定的泛型方法,则可以按照您的方式应用它,但需要这样做(您使用Execute方法演示的内容):

public void MyGenericMethod<T>(Func<T> func)
{ 

} 

首先注意 T,我们正在指定T的存在。

您的代码可能存在更多问题,但我相信,乍一看,这是您遇到问题的关键。

对于返回变量类型,您可能希望的最好的方法是返回一个普通的object。或者,使用dynamic类型,我不会想到这将是要走的路,不会推荐它;但是,你不能将返回类型从实际类型转换为void。

答案 1 :(得分:0)

新方法:操作Encapsulator现在将返回一个虚拟结果(始终为true)。

public class Encapsulator
{
    public static Encapsulator<bool> CreateEncapsulator(Action action)
    {
        return new Encapsulator<bool>(() =>
            {
                action();
                return true;
            });
    }

    public static Encapsulator<T> CreateEncapsulator<T>(Func<T> func)
    {
        return new Encapsulator<T>(func);
    }
}

public class Encapsulator<T>
{
    private Func<T> _function;

    internal Encapsulator(Func<T> func)
    {
        this._function = func;
    }

    public T Execute()
    {
        try
        {
            object res = this._function();
            Nullable<bool> bres = res as Nullable<bool>;

            if (bres.HasValue)
            {
                if (!bres.Value)
                    Console.WriteLine("NOT TRUE!");
                //do something
            }

            return (T)res;

        }
        catch (Exception ex)
        {
            //do something
            throw;
        }
    }
}

调用代码:

var withDummyReturn = Encapsulator.CreateEncapsulator(() => Console.WriteLine("Great"));
withDummyReturn.Execute();
var withReturn = Encapsulator.CreateEncapsulator<bool>(() => true);
bool res = withReturn.Execute();