C# 使用参数Func重载方法<;T>;

C# 使用参数Func重载方法<;T>;,c#,linq,overloading,C#,Linq,Overloading,我想创建几个重载方法,它们接受Func参数。重载方法应使用参数中定义的最通用类型调用该方法。下面是我的方法的一个快速示例,以及我如何调用它们: public static TResult PerformCaching<TResult, T1>(Func<T1, TResult> func, T1 first, string cacheKey) { return PerformCaching((t, _, _) => func, first, null, nu

我想创建几个重载方法,它们接受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;
}
publicstatictresult执行缓存(Func-Func,T1-first,stringcachekey)
{
返回PerformCaching((t,,)=>func,first,null,null,cacheKey);
}
public static TResult PerformCaching(Func-Func,T1第一,T2第二,字符串缓存键)
{
返回PerformCaching((t,t2,)=>func,first,second,null,cacheKey);
}
公共静态树结果执行缓存(Func Func、T1第一、T2第二、T3第三、字符串缓存键)
{
模型数据=获取(cacheKey);
如果(数据==null)
{
添加(缓存键);
数据=函数调用(第一、第二、第三);
更新(数据);
}
返回数据;
}

有可能让它像这样工作吗?另一个问题是func在到达最终方法时发生了什么。它是用一个参数执行它(当调用第一个方法时),还是用所有三个参数调用它。

不,这种方法不起作用。您试图将
Func
传递给接受
Func
的方法,但这根本不起作用。我建议改成这样:

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);
}
public static TResult PerformCaching(Func-Func,
字符串缓存键)
{
//在这里做真正的事情
//您可能会发现ConcurrentDictionary很有帮助。。。
}
公共静态结果执行缓存
(Func Func,T1优先,字符串缓存键)
{
返回PerformCaching(()=>func(第一个),cacheKey);
}
公共静态结果执行缓存
(Func Func,T1第一,T2第二,字符串缓存键)
{
返回PerformCaching(()=>func(第一、第二)、cacheKey);
}
公共静态结果执行缓存
(Func Func,T1第一,T2第二,T3第三,
字符串缓存键)
{
返回PerformCaching(()=>func(第一、第二、第三)、cacheKey);
}

您必须从
Func
投影到
Func
。这并不难,但我不确定这是最好的方法。您还存在其他通用问题,比如转换为模型(我将其转换为字符串)。更好的方法可能是类似于
Cache.Retrieve(字符串cashKey,Func missingItemFactory)
。然后调用like
Cache.Retrieve(“model1”,()=>repository.Get(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) { }
void Main()
{
Func f1=s=>“一”;
Func f2=(s1,s2)=>“两个”;
Func f3=(s1、s2、s3)=>“三”;
控制台写入线(执行缓存(f1,“一”,“f1”);
控制台写入线(执行缓存(f1,“一”,“f1”);
控制台写入线(执行缓存(f2,“一”、“二”、“f2”);
控制台写入线(执行缓存(f2,“一”、“二”、“f2”);
控制台写入线(执行缓存(f3,“一”、“二”、“三”、“f3”);
控制台写入线(执行缓存(f3,“一”、“二”、“三”、“f3”);
}
//在此处定义其他方法和类
公共静态TResult执行缓存(Func Func,T1优先,字符串cacheKey)
{
返回PerformCaching((t,t2,t3)=>func(t),first,null,null,cacheKey);
}
public static TResult PerformCaching(Func-Func,T1第一,T2第二,字符串缓存键)
{
返回PerformCaching((t,t2,t3)=>func(t,t2),第一个,第二个,null,cacheKey);
}
公共静态树结果执行缓存(Func Func、T1第一、T2第二、T3第三、字符串缓存键)
{
TResult data=Get(cacheKey);
如果(数据==null)
{
添加(缓存键);
数据=函数调用(第一、第二、第三);
更新(数据);
}
返回数据;
}
公共静态T Get(字符串CashKey){返回默认值(T);}
公共静态void Add(字符串CashKey){}
公共静态无效更新(T数据){}

您尝试了什么?什么不起作用?谢谢Jon,这个很有魅力。我在想调用这些方法的顺序是错误的。@ChristiaanV我就是搞不懂?坚持使用单个方法
执行缓存(Func-Func,string-cacheKey)
在不限制参数数量的情况下删除不必要的重载不是更有用吗。它仍然支持调用:
PerformCaching(()=>ActualMethod(1),cacheKey)
通过
PerformCaching(()=>ActualMethod(1,“s”,“c”,“…),cacheKey)
。我做错什么了?