我想创建一些接受Func参数的重载方法。重载方法应该使用参数中定义的最通用类型调用该方法。下面是我的方法的一个简单示例,以及我想如何调用它们:
public static TResult PerformCaching<TResult, T1>(Func<T1, TResult> func, T1 first, string cacheKey)
{
return PerformCaching((t, _, _) => func, first, null, null, cacheKey);
}
public static TResult PerformCaching<TResult, T1, T2>(Func<T1, T2, TResult> func, T1 first, T2 second, string cacheKey)
{
return PerformCaching((t, t2, _) => func, first, second, null, cacheKey);
}
public static TResult PerformCaching<TResult, T1, T2, T3>(Func<T1, T2, T3, TResult> func, T1 first, T2 second, T3 third, string cacheKey)
{
Model data = Get(cacheKey);
if(data == null)
{
Add(cacheKey);
data = func.Invoke(first, second, third);
Update(data);
}
return data;
}
是否有可能让它像这样工作?另一个问题是当func到达最终方法时会发生什么。它会用一个参数执行它(当第一个方法被调用时),还是用所有三个参数调用它。
答案 0 :(得分:7)
不,这种方法不起作用。您试图将Func<T1, TResult>
传递给接受Func<T1, T2, T3, TResult>
的方法 - 但这根本不起作用。我建议换成这样的东西:
public static TResult PerformCaching<TResult>(Func<TResult> func,
string cacheKey)
{
// Do real stuff in here
// You may find ConcurrentDictionary helpful...
}
public static TResult PerformCaching<T1, TResult>
(Func<T1, TResult> func, T1 first, string cacheKey)
{
return PerformCaching(() => func(first), cacheKey);
}
public static TResult PerformCaching<T1, T2, TResult>
(Func<T1, T2, TResult> func, T1 first, T2 second, string cacheKey)
{
return PerformCaching(() => func(first, second), cacheKey);
}
public static TResult PerformCaching<T1, T2, T3, TResult>
(Func<T1, T2, T3, TResult> func, T1 first, T2 second, T3 third,
string cacheKey)
{
return PerformCaching(() => func(first, second, third), cacheKey);
}
答案 1 :(得分:0)
您必须从Func<T, T1, T2>
投射到Func<T, T1, T2, T3>
。这并不难,但我不确定这是最好的方法。您还有其他一般性问题,例如转换为Model(我转换为字符串)。更好的方法可能类似于Cache.Retrieve<TResult>(string cashKey, Func<TResult> missingItemFactory)
。然后你会打电话给Cache.Retrieve("model1", () => repository.Get<Model>(myId))
,然后在方法中调用if (data == null) data = missingItemFactory();
。
无论如何,解决方案如下。
void Main()
{
Func<string, string> f1 = s => "One";
Func<string, string, string> f2 = (s1, s2) => "Two";
Func<string, string, string, string> f3 = (s1, s2, s3) => "Three";
Console.WriteLine(PerformCaching(f1, "one", "f1"));
Console.WriteLine(PerformCaching(f1, "one", "f1"));
Console.WriteLine(PerformCaching(f2, "one", "two", "f2"));
Console.WriteLine(PerformCaching(f2, "one", "two", "f2"));
Console.WriteLine(PerformCaching(f3, "one", "two", "three", "f3"));
Console.WriteLine(PerformCaching(f3, "one", "two", "three", "f3"));
}
// Define other methods and classes here
public static TResult PerformCaching<TResult, T1>(Func<T1, TResult> func, T1 first, string cacheKey)
{
return PerformCaching<TResult, T1, string, string>((t, t2, t3) => func(t), first, null, null, cacheKey);
}
public static TResult PerformCaching<TResult, T1, T2>(Func<T1, T2, TResult> func, T1 first, T2 second, string cacheKey)
{
return PerformCaching<TResult, T1, T2, string>((t, t2, t3) => func(t, t2), first, second, null, cacheKey);
}
public static TResult PerformCaching<TResult, T1, T2, T3>(Func<T1, T2, T3, TResult> func, T1 first, T2 second, T3 third, string cacheKey)
{
TResult data = Get<TResult>(cacheKey);
if(data == null)
{
Add(cacheKey);
data = func.Invoke(first, second, third);
Update(data);
}
return data;
}
public static T Get<T>(string CashKey) { return default(T); }
public static void Add(string CashKey) { }
public static void Update<T>(T data) { }