C# -- 使用委托简化代码

在C#编程中通常会碰到许多重复劳动的情况,而面向对象编程的原则就是消除这些重复劳动,增加代码重用性。我们一般都会对其封装成方法,然后调用,但还是会碰到一些看似不得已的重复劳动的情况。比如在平时写代码时候,按照规范,有些代码需要加try-catch,来捕捉异常,就像这样:

public class FuncTest
    {
        public void Method1()
        {
            try
            {
                int result = Cols(0);
                Console.WriteLine($"相除后的结果是{result}");
            }
            catch (Exception ex)
            {
                Console.WriteLine("程序发生错误!!!");
            }
            Console.WriteLine("完!!!");
        }
        public void Method2()
        {
            try
            {
                
            }
            catch (Exception ex)
            {
                
            }
        }
        public int Cols(int x)
        {
            return 10 / x;
        }
    }

一般项目里都是这样写,每个页面的try-catch也不是很多,但是如果使用的较多的情况写起来就比较恶心了。。。

但是C#有个很碉堡的东西叫委托,我们可以用Action或Func委托把数据库访问的逻辑封装起来,这样就只要定义一次try-catch的规则就OK了。就像这样:

不要求返回值的:

public class FuncTest
    {
        public void Method1()
        {
            TryExcute(() =>
            {
                int result = Cols(0);
                Console.WriteLine($"相除后的结果是{result}");
            }, "Method1");
            
            Console.WriteLine("完!!!");
        }
        public void Method2()
        {
            TryExcute(() =>
            {
                //...
            }, "Method2");
        }
        public int Cols(int x)
        {
            return 10 / x;
        }
        //将try-catch封装,然后那个方法需要使用,就是用将方法作为参数扔给委托
        public void TryExcute(Action method,string funcName = null)
        {
            try
            {
                method();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{method} 函数发生异常!!!");
            }
        }
    }

以此类推,可以写几个比较常用的TryExecute方法,根据需要,然后调用:

带返回值的:

public T TryExecute<T>(Func<T> func, string funcName = null)
{
    try
    {
        return func();
    }
    catch (Exception e)
    {
        
    }
}

支持.NET 4.5 async await关键词的:

public async Task<T> TryExecuteAsync<T>(Func<Task<T>> func, string funcName = null)
{
    try
    {
        return await func();
    }
    catch (Exception e)
    {
        
    }
}

自定义包裹类的,比如Request/Response模式:

public Response<T> TryExecute<T>(Func<Response<T>> func, string funcName = null)
{
    try
    {
        return func();
    }
    catch (Exception e)
    {
        
        return new Response<T>
        {
            Item = default(T),
            Message = e.Message
        };
    }
}

所有带返回值的调用也很简单,就像这样:

public int Method1()
{
    return TryExecute(() =>
    {
        return 0;
    }, "Method1");
}

但是注意async的那只,需要指定一个async lambda表达式,就像这样:

public async Task<int> Method1()
{
    return await TryExecuteAsync(async () =>
    {
        return await SomeOperation();
    }, "Method1");
}

之前一直不知道委托到底有毛用,现在一看真吊!

原文地址:https://www.cnblogs.com/dcy521/p/13922771.html