哪里
where
可以在 C#中实现两个目的:在泛型参数中键入约束,并过滤 LINQ 查询。
在通用类中,让我们考虑一下
public class Cup<T>
{
// ...
}
T 称为类型参数。类定义可以对可以为 T 提供的实际类型施加约束。
可以应用以下类型的约束:
- 值类型
- 参考类型
- 默认构造函数
- 继承和实施
值类型
在这种情况下,只能提供 struct
s(包括’原始’数据类型,如 int
,boolean
等)
public class Cup<T> where T : struct
{
// ...
}
参考类型
在这种情况下,只能提供类类型
public class Cup<T> where T : class
{
// ...
}
混合值/参考类型
有时,需要将类型参数限制为数据库中可用的参数,这些参数通常会映射到值类型和字符串。由于必须满足所有类型限制,因此无法指定 where T : struct or string
(这不是有效的语法)。解决方法是将类型参数限制为 IConvertible
,其内置类型为“… Boolean,SByte,Byte,Int16,UInt16,Int32,UInt32,Int64,UInt64,Single,Double,Decimal,DateTime,Char 和 String。 “ 其他对象可能会实现 IConvertible,尽管这在实践中很少见。
public class Cup<T> where T : IConvertible
{
// ...
}
默认构造函数
仅允许包含默认构造函数的类型。这包括值类型和包含默认(无参数)构造函数的类
public class Cup<T> where T : new
{
// ...
}
继承和实施
只能提供从某个基类继承或实现某个接口的类型。
public class Cup<T> where T : Beverage
{
// ...
}
public class Cup<T> where T : IBeer
{
// ...
}
约束甚至可以引用另一个类型参数:
public class Cup<T, U> where U : T
{
// ...
}
可以为类型参数指定多个约束:
public class Cup<T> where T : class, new()
{
// ...
}
前面的示例显示了类定义的泛型约束,但是在提供类型参数的任何地方都可以使用约束:类,结构,接口,方法等
where
也可以是 LINQ 子句。在这种情况下,它类似于 SQL 中的 WHERE
:
int[] nums = { 5, 2, 1, 3, 9, 8, 6, 7, 2, 0 };
var query =
from num in nums
where num < 5
select num;
foreach (var n in query)
{
Console.Write(n + " ");
}
// prints 2 1 3 2 0