LINQ 标准查询操作符(4)


var q =
Enumerable.Range(0, 10);
foreach (var item in q)
{
Console.WriteLine(item);
}


4. Repeat
Repeat操作符用于生成包含一个重复值的集合。它需要两个参数,第一个参数是任意类型的元素,第二个参数是生成的序列中所包含此元素的数量。下面的示例演示了使用Repeat来生成一个包含10个0的序列:

复制代码 代码如下:


var q =
Enumerable.Repeat(0, 10);
foreach (var item in q)
{
Console.WriteLine(item);
}


十、转换操作符
转换操作符是用来实现将输入对象的类型转变为序列的功能。名称以“As”开头的转换方法可更改源集合的静态类型但不枚举(延迟加载)此源集合。名称以“To”开头的方法可枚举(即时加载)源集合并将项放入相应的集合类型。
1. AsEnumerable
所有实现了IEnumerable<T>接口的类型都可以调用此方法来获取一个IEnumerable<T>集合。此方法一般仅用于实现类中的方法与IEnumerable<T>接口方法重名时。例如,实现类Test中有一个Where方法,当使用Test对象调用Where时,将执行Test自身的Where方法过程。如果要执行IEnumerable<T>的Where方法,便可以使用AsEnumerable进行进行转换后,再调用Where方法即可。当然,将实现类Test隐式转换为IEnumerable<T>接口,再调用接口的Where方法也能达到同样的效果。以下的代码演示了这一过程:

复制代码 代码如下:


class AsEnumerableTest<T> : List<T>
{
public void Where(Func<T, bool> func)
{
Console.WriteLine("AsEnumerableTest的Where方法");
}
}
public static void AsEnumerable()
{
AsEnumerableTest<int> q = new AsEnumerableTest<int>() { 1,2,3,4 };
q.Where(r => r < 3);
//q.AsEnumerable().Where(r => r < 3);
//IEnumerable<int> i = q;
//i.Where(r => r < 3);
}


2. Cast
Cast<T> 方法通过提供必要的类型信息,可在IEnumerable(非泛型)的派生对象上调用Cast<T> 方法来获得一个IEnumerable<T>对象。例如,ArrayList 并不实现 IEnumerable<T>,但通过调用 ArrayList 对象上的 Cast<T>(),就可以使用标准查询运算符查询该序列。
如果集合中的元素无法强制转换为 T 类型,则此方法将引发异常。以下代码演示了这一过程:

复制代码 代码如下:


ArrayList array = new ArrayList();
array.Add("Bob");
array.Add("Jack");
array.Add(1);
foreach (var item in array.Cast<string>())
{
Console.WriteLine(item);
}


运行此代码,可以输出“Bob”、“Jack”,然后会报出一个异常“无法将int强制转换为string”,这说明Cast方法也是延迟执行实现的,只有在枚举过程中才将对象逐个强制转换为T类型。
3. OfType
OfType <T> 方法通过提供必要的类型信息,可在IEnumerable(非泛型)的派生对象上调用OfType <T> 方法来获得一个IEnumerable<T>对象。执行OfType<T>方法将返回集合中强制转换类型成功的所有元素。也就是说,OfType<T>方法与Cast<T> 方法的区别在于,如果集合中的元素在强制转换失败的时候会跳过,而不是抛出异常。
4. ToArray
ToArray 操作符可以在IEnumerable<T> 类型的任何派生对象上调用,返回值为T类型的数组。
5. ToDictionary
ToDictionary操作符根据指定的键选择器函数,从IEnumerable<T>创建一个Dictionary<TKey, TValue>。下面的示例中,将查询到的产品类别集合转换为Dictionary<类别ID,类别名称>的键-值集合:

复制代码 代码如下:


using (NorthwindDataContext db = new NorthwindDataContext())
{
db.Log = Console.Out; //将生成的T-SQL语句输出到控制台中
//方法语法
var q =
db.Categories
.ToDictionary
(
c => c.CategoryID,
c => c.CategoryName
);
foreach (var item in q)
{
Console.WriteLine("{0} - {1}",item.Key,item.Value);
}
}


需要注意的是,如果省略ToDictionary方法的第二个参数(值选择函数),那么Value将会保存一个类别对象。还有,如果Key为null,或者出现重复的Key,都将导致抛出异常。
6. ToList
ToList操作符可以在IEnumerable<T> 类型的任何派生对象上调用,返回值为List<T>类型的对象。
7. ToLookup
ToLookup操作符将创建一个 Lookup<TKey, TElement>对象,这是一个one-to-many集合,一个Key可以对应多个Value。以下的示例以产品表的所有数据作为数据源,以类别ID作为Key调用了ToLookup方法,然后遍历返回的Lookup<TKey, TElement>对象,输出了类别ID以及此类别下的所有产品名称:

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjjxpz.html