好了,以示我的代碼看起來像(這一點也適用,但不一定漂亮):C#功能使用重載的方法
public delegate Response Func<R1>(ref R1 out1);
public delegate Response Func<T1, R1>(T1 in1, ref R1 out1);
public delegate Response Func<T1, T2, R1>(T1 in1, T2 in2, ref R1 out1);
public delegate Response Func<T1, T2, T3, R1>(T1 in1, T2 in2, T3 in3, ref R1 out1);
public delegate Response Func<T1, T2, T3, T4, R1>(T1 in1, T2 in2, T3 in3, T4 in4, ref R1 out1);
public delegate Response Func<T1, T2, T3, T4, T5, R1>(T1 in1, T2 in2, T3 in3, T4 in4, T5 in5, ref R1 out1);
public delegate Response Func<T1, T2, T3, T4, T5, T6, R1>(T1 in1, T2 in2, T3 in3, T4 in4, T5 in5, T6 in6, ref R1 out1);
public static Response Query<R1>(Func<R1> method, ref R1 out1)
{
return QueryAll<object, object, object, object, object, object, R1>(method, null, null, null, null, null, null, ref out1);
}
public static Response Query<T1, R1>(Func<T1, R1> method, T1 in1, ref R1 out1)
{
return QueryAll<T1, object, object, object, object, object, R1>(method, in1, null, null, null, null, null, ref out1);
}
public static Response Query<T1, T2, R1>(Func<T1, T2, R1> method, T1 in1, T2 in2, ref R1 out1)
{
return QueryAll<T1, T2, object, object, object, object, R1>(method, in1, in2, null, null, null, null, ref out1);
}
public static Response Query<T1, T2, T3, R1>(Func<T1, T2, T3, R1> method, T1 in1, T2 in2, T3 in3, ref R1 out1)
{
return QueryAll<T1, T2, T3, object, object, object, R1>(method, in1, in2, in3, null, null, null, ref out1);
}
public static Response Query<T1, T2, T3, T4, R1>(Func<T1, T2, T3, T4, R1> method, T1 in1, T2 in2, T3 in3, T4 in4, ref R1 out1)
{
return QueryAll<T1, T2, T3, T4, object, object, R1>(method, in1, in2, in3, in4, null, null, ref out1);
}
public static Response Query<T1, T2, T3, T4, T5, R1>(Func<T1, T2, T3, T4, T5, R1> method, T1 in1, T2 in2, T3 in3, T4 in4, T5 in5, ref R1 out1)
{
return QueryAll<T1, T2, T3, T4, T5, object, R1>(method, in1, in2, in3, in4, in5, null, ref out1);
}
public static Response Query<T1, T2, T3, T4, T5, T6, R1>(Func<T1, T2, T3, T4, T5, T6, R1> method, T1 in1, T2 in2, T3 in3, T4 in4, T5 in5, T6 in6, ref R1 out1)
{
return QueryAll<T1, T2, T3, T4, T5, T6, R1>(method, in1, in2, in3, in4, in5, in6, ref out1);
}
private static Response QueryAll<T1, T2, T3, T4, T5, T6, R1>(Delegate method, T1 in1, T2 in2, T3 in3, T4 in4, T5 in5, T6 in6, ref R1 out1)
{
try
{
Response response = null;
// Test if the method's class implements ICacheable
if (method.GetType() is ICacheable)
{
// Try to get the value from the cache if available
out1 = ((ICacheable)method.Target).Get<R1>(out1);
// If not null, return the value and exit
if (out1 != null)
return null;
else
{
// Value is null, but should be cached, so attempt to load to cache and return it
if (in6 != null)
response = ((Func<T1, T2, T3, T4, T5, T6, R1>)method)(in1, in2, in3, in4, in5, in6, ref out1);
else if (in5 != null)
response = ((Func<T1, T2, T3, T4, T5, R1>)method)(in1, in2, in3, in4, in5, ref out1);
else if (in4 != null)
response = ((Func<T1, T2, T3, T4, R1>)method)(in1, in2, in3, in4, ref out1);
else if (in3 != null)
response = ((Func<T1, T2, T3, R1>)method)(in1, in2, in3, ref out1);
else if (in2 != null)
response = ((Func<T1, T2, R1>)method)(in1, in2, ref out1);
else if (in1 != null)
response = ((Func<T1, R1>)method)(in1, ref out1);
else
response = ((Func<R1>)method)(ref out1);
// If value from database is not null, save it in cache
if (out1 != null)
((ICacheable)method.Target).Set<R1>(out1);
return response;
}
}
else
{
// Get data from database
if (in6 != null)
response = ((Func<T1, T2, T3, T4, T5, T6, R1>)method)(in1, in2, in3, in4, in5, in6, ref out1);
else if (in5 != null)
response = ((Func<T1, T2, T3, T4, T5, R1>)method)(in1, in2, in3, in4, in5, ref out1);
else if (in4 != null)
response = ((Func<T1, T2, T3, T4, R1>)method)(in1, in2, in3, in4, ref out1);
else if (in3 != null)
response = ((Func<T1, T2, T3, R1>)method)(in1, in2, in3, ref out1);
else if (in2 != null)
response = ((Func<T1, T2, R1>)method)(in1, in2, ref out1);
else if (in1 != null)
response = ((Func<T1, R1>)method)(in1, ref out1);
else
response = ((Func<R1>)method)(ref out1);
return response;
}
}
catch (Exception exc)
{
CustomException exception = exc.ToCustomException();
exception.Code = ResponseCodes.UnknownError;
throw exception;
}
}
這是數據抽象層。同樣,我的問題是我想讓開發人員傳遞一個方法和多達6個參數。但是,我只想要一個主要方法來包含我所有的邏輯,以便更容易維護。然後,基於某些條件(是否是緩存中的對象),調用數據層上的方法以從存儲庫中讀取對象,存儲在緩存中,然後將對象返回給控制器。
有沒有更好的方法來做到這一點比多個if/else語句如下?
你可能會考慮在'params'關鍵字,但我不知道你想什麼是可能的。 – vesan
不幸的是,C#沒有使這個更好的類型安全的機制。它沒有可變的泛型,代表沒有共同的接口,你只需要求助於這樣的解決方案或犧牲類型安全性,並使用反射或建立動態表達式。 –
我不認爲有任何合理的方法來做到這一點。雖然我覺得它有點令人困惑,但可能要稍微改寫一下你的問題。我可以發表一個集中這種邏輯的想法,但這是一種解決方法。這個概念是爲每個可能的arg創建一個字段的類型,使用靜態初始化器來實例化它,然後在你調用的類型上有一個'Query'方法,並且它具有所有的if/else邏輯來選擇哪個方法基於它的屬性的無效性來調用。我會說這與理想情況很不相稱,但我不知道你會如何獲得這種靈活性。 – evanmcdonnal