![](/img/trans.png)
[英]Is there a way to avoid overloading a method with Func<T, …> argument for each Func parameter count
[英]Overloading a method with parameter Func<T>
我想創建一些接受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到達最終方法時會發生什么。 它會用一個參數執行它(當第一個方法被調用時)或是用所有三個參數調用它。
不,這種方法不起作用。 您將嘗試將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);
}
您必須從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) { }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.