可以创建引用通用方法的Func
object吗?像LINQ OrderBy:
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector
)
答案 0 :(得分:20)
如果我理解正确,你会问你是否可以在匿名方法中引用泛型方法。
答案是肯定的。
例如,假设您希望某些Func
按排序顺序返回IEnumerable<int>
对象的元素(与OrderBy<int, int>
完全相同)。你可以这样做:
Func<IEnumerable<int>, Func<int, int>, IOrderedEnumerable<int>> orderByFunc =
System.Linq.Enumerable.OrderBy<int, int>;
然后你可以像其他任何人一样使用这个Func
:
int[] ints = new int[] { 1, 3, 5, 4, 7, 2, 6, 9, 8 };
// here you're really calling OrderBy<int, int> --
// you've just stored its address in a variable of type Func<...>
foreach (int i in orderByFunc(ints, x => x))
Console.WriteLine(i);
输出:
1
2
3
4
5
6
7
8
9
另一方面,如果您在询问是否可以创建“通用匿名方法”,如下所示:
Func<T> getDefault<T> = () => default(T);
那么这取决于你的背景。这可以在已将T
声明为泛型类型参数的上下文中完成 - 即,在泛型类或泛型方法中。 (参见Freddy Rios的回答。)不幸的是,在这样的背景之外,这是非法的。
答案 1 :(得分:4)
是的,但这取决于上下文 - 如果你已经在使用泛型,只需在上下文中使用T /如果没有,那么你已经知道了特定的类型。在后面,如果你需要在一个方法上重用一点逻辑,你可能已经将它移到一个方法中了,所以就像我下面的第二个例子一样。
2个样本:
public T Something<T>() {
Func<T> someFunc = () => { return default(T); };
return someFunc();
}
public Func<T> GetDefaultCreator<T>() {
return () => { return default(T); };
}
答案 2 :(得分:0)
这样的东西?
Func<Nullable<int>, string> myFunc = c => c.HasValue ? c.ToString() : "null";
成功编译,你可以将任何函数分配给Nullable并返回一个字符串。
答案 3 :(得分:0)
是的,但是您需要指定类型参数
func<int> f = myClass.returnsT<int>;
其中
class myClass
{
T returnsT<T>()
{...}
}
如果没有类型参数
,它将无法工作答案 4 :(得分:0)
我做过这样的事情:
public static class Helper{
public static IEnumerable<KeyValuePair<string, string>> ToPairs(this NameValueCollection Form)
{
return Form.AllKeys.Cast<string>()
.Select(key => new KeyValuePair<string, string>(key, Form[key]));
}
}
此方法已成为C#web开发中request.form的扩展方法。
答案 5 :(得分:0)
我想我明白了:给定函数static TResult DoSomeStuff<T, TResult>(T obj)
,你可以创建一个Func<T, TResult>
,使它引用上面的函数,在创建引用时没有给出类型参数。
我认为这可行(欢迎你来测试一下,我现在附近没有C#):
class UselessClass<T, TResult> { // If it's a static method, this is fine: public Func<T, TResult> DaFunc = RelevantClass.DoSomeStuff<T, TResult>; // If not, something like this is needed: public UselessClass(SomeClassWhereTheFunctionIs from) { DaFunc = from.DoSomeStuff<T, TResult>; } }
此外,在OrderBy中,它实际上不是通用委托。这是变量的声明。当给出函数时,可以从中推断出类型。