[英]How to refactor “using” statement to avoid code duplication?
假設我有以下方法:
public string GetSchedules(string request)
{
using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint))
{
return soapClient.GetSchedules(AuthenticationInfo, request);
}
}
public string GetCountryList(string request)
{
using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint))
{
return soapClient.GetCountryList(AuthenticationInfo, request);
}
}
public string GetCarriers(string request)
{
using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint))
{
return soapClient.GetCarriers(AuthenticationInfo, request);
}
}
如您所見,唯一不同的是所調用方法的名稱。 我該如何重構這些方法以僅應用一次“ using”語句並避免代碼重復?
對我來說,您所擁有的還可以,但是如果您要排除這些因素,則可以使用Func
和lambdas。 遵循以下原則:
public string GetSchedules(string request)
{
return Worker((c) => c.GetSchedules(AuthenticationInfo, request));
}
public string GetCountryList(string request)
{
return Worker((c) => c.GetCountryList(AuthenticationInfo, request));
}
public string GetCarriers(string request)
{
return Worker((c) => c.GetCarriers(AuthenticationInfo, request));
}
private string Worker(Func<SoapClientClassGoesHere, string> f)
{
using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint))
{
return f(soapClient);
}
}
Func<A, R>
意思是“一個具有A
類型參數並返回R
類型值的函數”(對於具有兩個參數的函數,您可以具有Func<A, B, R>
。)
有關此問題和此問題的更多信息,請參見Func<>
和lambdas(還有很多,這是一個很豐富的主題)。
這是ideone.com上的一個實時示例 (一個非常愚蠢的實時示例,但它演示了這個概念):
using System;
using System.Collections.Generic;
class Foo {
public string GetSchedules(string request)
{
return Worker((c) => c[request]);
}
public string GetCountryList(string request)
{
return Worker((c) => c[request].ToUpper());
}
public string GetCarriers(string request)
{
return Worker((c) => c[request].ToLower());
}
private string Worker(Func<Dictionary<string,string>, string> f)
{
var d = new Dictionary<string, string>();
d.Add("1", "One");
d.Add("2", "Two");
d.Add("3", "Three");
return f(d);
}
}
public class Test
{
public static void Main()
{
var f = new Foo();
Console.WriteLine(f.GetSchedules("1"));
Console.WriteLine(f.GetCountryList("1"));
Console.WriteLine(f.GetCarriers("1"));
}
}
那里確實沒有太多重復。 仍然,
public ServiceReference1.CustomDataTimetableToolKitServicesSoapClient NewClient()
{
return new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint)
}
using (var client = NewClient()) {
return soapClient.GetCountryList(AuthenticationInfo, request);
}
另外,由於所有方法都帶有一個string
參數並返回一個string
,因此很容易編寫一個方法來全部調用它們,並將操作作為委托傳遞給call。 不幸的是,我現在沒有時間為您寫這些。
您可以通過以下方式使用lambda函數:
public string GetCarriers(string request)
{
return Get((authInfo, request) => soapClient.GetCarriers(authInfo, request), request);
}
...
public string Get(Func<AuthenticationInfo, string, string> action, string request) {
using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint))
{
return action(AuthenticationInfo, request)
}
}
我不知道是否可以編譯,但是您知道了。
編輯:正如@Tim S.所注意到的,此代碼可能會更短:
public string GetCarriers(string request)
{
return Get(soapClient.GetCarriers, request);
}
...
public string Get(Func<AuthenticationInfo, string, string> action, string request) {
using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint))
{
return action(AuthenticationInfo, request)
}
}
編輯2:客戶端超出范圍。 因此正確的代碼是:
public string GetCarriers(string request)
{
return Get((client, authInfo, request) => client.GetCarriers(authInfo, request));
}
...
public string Get(Func<ISoapClient, AuthenticationInfo, string, string> action, string request) {
using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint))
{
return action(soapClient, AuthenticationInfo, request)
}
}
如果您的Projekt不太大,則可以使用以下命令(這有點混亂,容易出錯):
public string getX (string request, string x)
{
using (var soapClient = new ServiceReference1.CustomDataTimetableToolKitServicesSoapClient(EndpointConfiguratioName, Endpoint))
{
switch (x)
{
case "schedules":
return soapClient.GetSchedules(AuthenticationInfo, request);
break;
case "countryList":
return soapClient.GetCountryList(AuthenticationInfo, request);
break;
case "carriers":
return soapClient.GetCarriers(AuthenticationInfo, request);
break;
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.