好的,要显示我的代码看起来像什么(这可行,但不一定很漂亮):
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语句更好的方法吗?
答案 0 :(得分:2)
您可以将您的业务逻辑包含在另一个方法中,该方法具有您要调用的方法的参数
public static Response Query<R1>(Func<Tuple<Result, R1>> method, ref R1 @out)
{
Tuple<Result, R1> result = Logic(() => method());
@out = result.Item2;
return result.Item1;
}
public static Response Query<T1, R1>(Func<T1, Tuple<Result, R1>> method, T1 a, ref R1 @out)
{
Tuple<Result, R1> result = Logic(() => method(a));
@out = result.Item2;
return result.Item1;
}
public static Response Query<T1, T2, R1>(Func<T1, T2, Tuple<Result, R1>> method, T1 a, T2 b, ref R1 @out)
{
Tuple<Result, R1> result = Logic(() => method(a, b));
@out = result.Item2;
return result.Item1;
}
...
public static Tuple<Result, R1> Logic<R1>(Func<Tuple<Result, R1>> doMethod)
{
Tuple<Result, R1> result;
// logic
if(true) { result = doMethod(); }
...
// watch out if this doesn't get assigned, can cause problems downstream
return result;
}
答案 1 :(得分:0)
如果将T1,T2和其他参数作为单独的参数放入列表中会怎样? List<object>
你会得到类似的东西:
public static Response Query<L1,R1>(L1 in1, ref R1 out1)
{
// The SAME business logic with the same if/then statements
if (true)
out1 = method(in1, in2);
else
// Some other business logic
}
没有必要将method
作为参数传递,因为它总是采用相同的列表和相同数量的参数。
然后,您可以通过检查method
以及每个项目的类型,在in1.Count
中执行相同的操作:if (typeof(in1[0]) == T1) { ... }
答案 2 :(得分:0)
谢谢@ohmusama!我稍微调整了你的代码,因为我还需要在我的通用查询方法中使用返回的引用参数,但是你帮了很多!
以下是一个重载方法的最终答案:
public static Response Query<T1, T2, T3, T4, T5, T6, R1>(Func<T1, T2, T3, T4, T5, T6, Tuple<Response, R1>> method, T1 in1, T2 in2, T3 in3, T4 in4, T5 in5, T6 in6, ref R1 out1)
{
return QueryAll(() => method(in1, in2, in3, in4, in5, in6), ref out1);
}
private static Response QueryAll<R1>(Func<Tuple<Response, R1>> method, ref R1 out1)
{
try
{
Tuple<Response, R1> result;
// 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
result = method();
out1 = result.Item2;
// If value from database is not null, save it in cache
if (out1 != null)
((ICacheable)method.Target).Set<R1>(out1);
return result.Item1;
}
}
else
{
// Get data from database
result = method();
out1 = result.Item2;
return result.Item1;
}
}
catch (Exception exc)
{
CustomException exception = exc.ToCustomException();
exception.Code = ResponseCodes.UnknownError;
throw exception;
}
}