在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");
}
之前一直不知道委托到底有毛用,现在一看真吊!