我正在考虑创建一个动态linq查询,其中Where
运算符将根据用户的选择而有所不同,我对框架并不熟悉。我似乎需要使用Func
运算符,而我在使用这种语法时遇到了一些困难。
它做什么?这是什么意思?有人可以帮我理解它是如何使用的吗?
感谢。
答案 0 :(得分:4)
Func<>
只是一个预定义的委托模式:
protected bool SomeMethod(int input)
{
return true;
}
这是一种相当标准的方法。您可以创建一个以此签名为目标的委托:
public delegate bool MyMethodType(int input);
此委托仅适用于采用1整数并返回bool的方法。 FUNC&LT;&GT;试图通过使其成为通用来简化这一点:
public delegate T Func<T>();
public delegate U Func<T, U>(T input);
这实际上是一个Func&lt;&gt;是,只是一个普通的代表。这样,你可以说所有这些:
Func<int, bool> myMethod = SomeMethod;
MyMethodType myMethod = SomeMethod;
就LINQ而言,您可能会使用简写表达式语法;编译器会将表达式转换为代理:
.Where(x => x.SomeProperty > 10);
此陈述相当于:
.Where(delegate(int someProperty) { return someProperty > 10) })
这是所有编译器语法糖。
答案 1 :(得分:2)
Func<T>
只是一个类型名称。它不是一种特殊的语法。
lambda expressions是你需要包围的东西。例如,考虑一下:
myCollection.Where(item => item.Size == 10)
这意味着以下内容:获取集合myCollection
中的所有项目,检查每个项目的Size
属性是否等于10
,并仅考虑这种情况下的项目。< / p>
还有更多使用lambda表达式的运算符。在MSDN上有一个非常好的introduction to LINQ queries。
答案 2 :(得分:2)
只需记住Func<>
表示“功能”。函数基本上是一个返回结果的方法。
例如:
Func<bool>
表示“一个功能
返回布尔“Func<string,bool>
表示“一个功能
将字符串作为唯一输入参数
并返回一个布尔“Func<bool,string,int,string,bool>
意思是“一个4输入的功能
分别为的参数
类型bool,string,int和string ...
返回布尔“依此类推:<>
之间列出的类型是正确顺序的输入参数类型,除了最后一个是函数的返回类型。
现在,就Where
而言,它需要Func<TSource, Boolean>
作为参数,对吧?这意味着任何采用TSource
输入参数并返回Boolean
(又名bool
)的方法都可以(那里TSource
是集合中每个元素的类型)按Where
)过滤。
这意味着:Where
将仅保留所选方法将返回TSource
的每个true
。
示例: 您希望过滤第一个名称列表,只保留以“T”开头的名字。
string[] firstnames = new string[] { "Albert", "Terry", "Bob", Tom", "Joe" };
string[] firstnamesBeginningWithT = firstnames.Where(beginsWithT).ToArray();
beginsWithT
是这种方法:
bool beginsWithT(string firstname)
{
return firstname.StartWith("T");
}
存在一种快捷方式,这使得创建这种单行方法beginsWithT
变得不必要,这种方法可能只使用一次:
string[] firstnamesBeginningWithT = firstnames.Where(firstname => firstname.StartWith("T")).ToArray();
表示“对于集合中的每个元素,让我们方便地调用它firstname
,让我们看看它是否以T”开头。这个语法调用“lambda表达式”,相当于“没有名字的方法”,但是像beginsWithT
一样你会发现它需要一个string
作为输入并返回一个Boolean
。因此,它是一种Func<string,bool>
并符合Where
的需求。
希望你现在更加清楚! :-) Ssithra
答案 3 :(得分:1)
Func
不是运算符 - 它只是一个通用的委托类型。如果你看一下不同“重载”的签名,它应该变得更加清晰:
Func<TResult>
Func<T, TResult>
Func<T1, T2, TResult>
第一个是不带参数并返回值的函数,第二个函数接受一个参数并返回一个值,依此类推。
总而言之,它本质上是一种帮助程序类型,使您无需每次单独定义委托类型即可定义函数。
现在,这个真的都没有对动态Linq查询有多大帮助,但这就是你要求的......
答案 4 :(得分:0)
Func<T>
只是一个类型名称。它不是一种特殊的语法。
expression trees是你需要包围的东西。例如,考虑一下:
myCollection.Where(item => item.Size == 10)
如果myCollection
的类型为IQueryable<T>
,则编译器会将其转换为表示lambda表达式item => item.Size == 10
的表达式树。如果您使用它来访问(例如)SQL数据库,则此表达式将自动转换为SQL。
您可以按照MSDN上的说明Use Expression Trees to Build Dynamic Queries。特别是,您将使用许多static methods in the Expression
type动态构造这样的表达式树。