LINQ之延迟执行标准查询操作符(下)
2012-03-21 23:35
399 查看
操作符:Join
描述:基于匹配键对2个序列的元素进行关联,Join保留了TOuter中元素的顺序,并对于这些元素中的每一个元素,保留TInner中匹配元素的顺序.(来自msdn)
原型:2种
原型一:
publicstaticIEnumerable<TResult>Join<TOuter,TInner,TKey,TResult>(
thisIEnumerable<TOuter>outer,
IEnumerable<TInner>inner,
Func<TOuter,TKey>outerKeySelector,
Func<TInner,TKey>innerKeySelector,
Func<TOuter,TInner,TResult>resultSelector
)
Join的参数比较多,需要特别注意。举个例子:
List<Category>categories=newList<Category>
{
newCategory{Id=1,Name="Food"},
newCategory{Id=2,Name="Toys"},
newCategory{Id=3,Name="Fruit"}
};
List<Product>products=newList<Product>
{
newProduct{ProductId=201,ProductName="Chuckit",CategoryId=2},
newProduct{ProductId=202,ProductName="SafeMade",CategoryId=2},
newProduct{ProductId=101,ProductName="Taste",CategoryId=1},
newProduct{ProductId=102,ProductName="Canidae",CategoryId=1},
newProduct{ProductId=103,ProductName="Flavor",CategoryId=1}
};
varproductList=categories.Join(products,c=>c.Id,p=>p.CategoryId,
(c,p)=>new{c.Name,p.ProductName});
foreach(varproductinproductList)
{
Console.WriteLine("{0}----{1}",product.Name,product.ProductName);
}
在这个例子中,我们将categories和products通过categories.Id和products.CategoryId进行关联,返回一个新的对象的序列。
原型二略。
操作符:GroupJoin
描述:基于键相等对两个序列的元素进行关联并对结果进行分组.(来自msdn)
原型:
publicstaticIEnumerable<TResult>GroupJoin<TOuter,TInner,TKey,TResult>(
thisIEnumerable<TOuter>outer,
IEnumerable<TInner>inner,
Func<TOuter,TKey>outerKeySelector,
Func<TInner,TKey>innerKeySelector,
Func<TOuter,IEnumerable<TInner>,TResult>resultSelector
)
GroupJoin和Join很类似,GroupJoin会对返回的结果给予TOuter的Key进行分组。
对于返回的结果,TOuter中的一个元素可能对应多个TInner元素。
注意:如果TInner中没有TOuter的给定元素的关联元素,则该元素的匹配序列为空,但仍将出现在结果中.
举个例子:
List<Category>categories=newList<Category>
{
newCategory{Id=1,Name="Food"},
newCategory{Id=2,Name="Toys"},
newCategory{Id=3,Name="Fruit"}
};
List<Product>products=newList<Product>
{
newProduct{ProductId=201,ProductName="Chuckit",CategoryId=2},
newProduct{ProductId=202,ProductName="SafeMade",CategoryId=2},
newProduct{ProductId=101,ProductName="Taste",CategoryId=1},
newProduct{ProductId=102,ProductName="Canidae",CategoryId=1},
newProduct{ProductId=103,ProductName="Flavor",CategoryId=1}
};
varproductList=categories.GroupJoin(products,c=>c.Id,p=>p.CategoryId,
(c,ps)=>new{c.Name,Products=ps.Select(p=>p.ProductName)});
foreach(varproductinproductList)
{
Console.WriteLine(product.Name+":");
foreach(variteminproduct.Products)
{
Console.WriteLine(item);
}
}
打印出来的结果是:
Food:
Taste
Canidae
Flavor
Toys:
Chuckit
SafeMade
Fruit:
我们可以发现Fruit这个category没有匹配的产品,但是也被打印出来了。
操作符:GroupBy
描述:GroupBy主要用来对输入序列进行分组,并且返回IGrouping<K,T>
原型:GroupBy提供了众多的原型,我们主要关注4个:
原型一:
publicstaticIEnumerable<IGrouping<TKey,TSource>>GroupBy<TSource,TKey>(
thisIEnumerable<TSource>source,
Func<TSource,TKey>keySelector
)
List<Product>products=newList<Product>
{
newProduct{ProductId=201,ProductName="Chuckit",CategoryId=2},
newProduct{ProductId=202,ProductName="SafeMade",CategoryId=2},
newProduct{ProductId=101,ProductName="Taste",CategoryId=1},
newProduct{ProductId=102,ProductName="Canidae",CategoryId=1},
newProduct{ProductId=103,ProductName="Flavor",CategoryId=1}
};
varproductList=products.GroupBy(p=>p.CategoryId).OrderBy(item=>item.Key);
foreach(varkeyGroupProductsinproductList)
{
Console.WriteLine(keyGroupProducts.Key+":");
foreach(varproductinkeyGroupProducts)
{
Console.WriteLine(product.ProductName);
}
}
输出结果:
1:
Taste
Canidae
Flavor
2:
Chuckit
SafeMade
原型一比较简单,主要包含2个参数,一个输入序列,另外一个是selector。
在这个例子中,我们通过对products序列进行按categoryid进行分组,然后按照分组后的key进行排序。
原型二:
publicstaticIEnumerable<IGrouping<TKey,TSource>>GroupBy<TSource,TKey>(
thisIEnumerable<TSource>source,
Func<TSource,TKey>keySelector,
IEqualityComparer<TKey>comparer
)
原型二为我们多提供了IEqualityComparer参数用以自定义比较方法
publicinterfaceIEqualityComparer<inT>
这个接口提供了2个方法boolEquals(Tx,Ty)和intGetHashCode(Tobj)2个方法
注意IEqualityComparer是根据Key来比较的,例如,我们可以写个comparer比较器:
publicclassProductEqualityComparer:IEqualityComparer<int>
{
publicboolEquals(intx,inty)
{
if(x==0)returnfalse;
if(y==0)returnfalse;
returnIsSameVendor(x)==IsSameVendor(y);
}
publicintGetHashCode(intobj)
{
intstart=1;
intend=100;
returnIsSameVendor(obj)?start.GetHashCode():end.GetHashCode();
}
publicboolIsSameVendor(intid)
{
returnid<100;
}
}
ProductEqualityComparercomparer=newProductEqualityComparer();
List<Product>products=newList<Product>
{
newProduct{ProductId=201,ProductName="Chuckit",CategoryId=2},
newProduct{ProductId=202,ProductName="SafeMade",CategoryId=200},
newProduct{ProductId=101,ProductName="Taste",CategoryId=1},
newProduct{ProductId=102,ProductName="Canidae",CategoryId=1},
newProduct{ProductId=103,ProductName="Flavor",CategoryId=1}
};
IEnumerable<IGrouping<int,Product>>productList=products.GroupBy(p=>p.CategoryId,comparer);
foreach(varkeyGroupProductsinproductList)
{
Console.WriteLine(keyGroupProducts.Key+":"+(comparer.IsSameVendor(keyGroupProducts.Key)?"SameVendor":"DiffVendor"));
foreach(varproductinkeyGroupProducts)
{
Console.WriteLine(product.ProductName);
}
}原型三:publicstaticIEnumerable<IGrouping<TKey,TElement>>GroupBy<TSource,TKey,TElement>(
thisIEnumerable<TSource>source,
Func<TSource,TKey>keySelector,
Func<TSource,TElement>elementSelector
)
与原型一不一样的是,原型一返回了与输入序列同样的类型元素,原型三可以根据自己的需求,返回所需的元素类型,我们来看个例子:
List<Product>products=newList<Product>
{
newProduct{ProductId=201,ProductName="Chuckit",CategoryId=2},
newProduct{ProductId=202,ProductName="SafeMade",CategoryId=2},
newProduct{ProductId=101,ProductName="Taste",CategoryId=1},
newProduct{ProductId=102,ProductName="Canidae",CategoryId=1},
newProduct{ProductId=103,ProductName="Flavor",CategoryId=1}
};
varproductList=products.GroupBy(p=>p.CategoryId,p=>new{p.ProductId,p.ProductName}).OrderBy(p=>p.Key);
foreach(varkeyGroupProductsinproductList)
{
Console.WriteLine("Category:"+keyGroupProducts.Key);
foreach(varproductinkeyGroupProducts)
{
Console.WriteLine("{0}-{1}",product.ProductId,product.ProductName);
}
}
我们返回的不再是Product,而是我们新建的一个匿名类型,包含ProductId和ProductName
原型四:
publicstaticIEnumerable<IGrouping<TKey,TElement>>GroupBy<TSource,TKey,TElement>(
thisIEnumerable<TSource>source,
Func<TSource,TKey>keySelector,
Func<TSource,TElement>elementSelector,
IEqualityComparer<TKey>comparer
)
原型四实际上是原型二和原型三的结合,比较简单,就不举例子了。
操作符:Distinct
描述:Distinct操作符主要用于过滤重复的元素,2个元素相等是通过GetHashCode和Equals来判断的,原型二为我们提供了自己写对等条件的方法
原型:2种
原型一:
publicstaticIEnumerable<TSource>Distinct<TSource>(
thisIEnumerable<TSource>source
)
这个原型很简单,我们借用msdn的例子来说明:
List<int>ages=newList<int>{21,46,46,55,17,21,55,55};
IEnumerable<int>distinctAges=ages.Distinct();
Console.WriteLine("Distinctages:");
foreach(intageindistinctAges)
{
Console.WriteLine(age);
}
输出结果:
Distinctages:
21
46
55
17
重复的46,55被过滤掉了。
原型二:
publicstaticIEnumerable<TSource>Distinct<TSource>(
thisIEnumerable<TSource>source,
IEqualityComparer<TSource>comparer
)
我们先定义一个相等比较器:
publicclassProductEqualityComparer:IEqualityComparer<Product>
{
publicboolEquals(Productx,Producty)
{
if(x==null||y==null)returnfalse;
returnx.ProductId==y.ProductId&&x.CategoryId==y.CategoryId;
}
publicintGetHashCode(Productobj)
{
intproductid=obj.ProductId;
intcategoryid=obj.CategoryId;
returnproductid.GetHashCode()+categoryid.GetHashCode();
}
}
然后,在查询的时候,应用这个比较器:
ProductEqualityComparercomparer=newProductEqualityComparer();
List<Product>products=newList<Product>
{
newProduct{ProductId=201,ProductName="Chuckit",CategoryId=2},
newProduct{ProductId=201,ProductName="CHUCKIT",CategoryId=2},
newProduct{ProductId=101,ProductName="Taste",CategoryId=1},
newProduct{ProductId=102,ProductName="Canidae",CategoryId=1},
newProduct{ProductId=103,ProductName="Flavor",CategoryId=1}
};
varproductList=products.Distinct(comparer);
foreach(varproductinproductList)
{
Console.WriteLine("{0}:{1}:{2}",product.CategoryId,product.ProductId,product.ProductName);
}
输出结果为:
2:201:Chuckit
1:101:Taste
1:102:Canidae
1:103:Flavor
可以发现,201这个product第二个ProductName为全大写的被过滤掉了,因为根据我们的相等比较器,两个201product是一样的。
操作符:Union
描述:连接2个序列,相同的元素只会保留一个
原型:2种
原型一:
publicstaticIEnumerable<TSource>Union<TSource>(
thisIEnumerable<TSource>first,
IEnumerable<TSource>second
)
这也是个很简单的操作符,我们还是来看个简单的例子:
List<int>int1=newList<int>{12,42,3,2};
List<int>int2=newList<int>{24,3};
varunitInts=int1.Union(int2);
foreach(varunitIntinunitInts)
{
Console.WriteLine(unitInt);
}
输出结果为:
12
42
3
2
24
int2的3被过滤掉了,因为int1已经存在3这个元素了
原型二为我们提供了相等比较器:
publicstaticIEnumerable<TSource>Union<TSource>(
thisIEnumerable<TSource>first,
IEnumerable<TSource>second,
IEqualityComparer<TSource>comparer
)
跟上面的Distinct的原型二类似,我们就不再举例了。
操作符:Intersect
描述:返回2个序列的交集
原型:2种
题外话:看到这里,其实我们就很容易猜出这2种原型是什么了,无非一种是采用默认对等比较的交集操作,另一种是可以自己提供相等比较器的方法
原型一:
publicstaticIEnumerable<TSource>Intersect<TSource>(
thisIEnumerable<TSource>first,
IEnumerable<TSource>second
)
原型二:
publicstaticIEnumerable<TSource>Intersect<TSource>(
thisIEnumerable<TSource>first,
IEnumerable<TSource>second,
IEqualityComparer<TSource>comparer
)
我们举个原型一的例子吧:
List<int>int1=newList<int>{12,42,3,2};
List<int>int2=newList<int>{24,3};
varunitInts=int1.Intersect(int2);
foreach(varunitIntinunitInts)
{
Console.WriteLine(unitInt);
}
结果集只会返回3。
操作符:Except
描述:该操作符返回存在于序列1但是不存在序列2的所有元素
原型:2种
原型一:
publicstaticIEnumerable<TSource>Except<TSource>(
thisIEnumerable<TSource>first,
IEnumerable<TSource>second
)
原型二:
publicstaticIEnumerable<TSource>Except<TSource>(
thisIEnumerable<TSource>first,
IEnumerable<TSource>second,
IEqualityComparer<TSource>comparer
)
我们举个原型一的例子:
List<int>int1=newList<int>{12,42,3,2};
List<int>int2=newList<int>{24,3};
varunitInts=int1.Except(int2);
foreach(varunitIntinunitInts)
{
Console.WriteLine(unitInt);
}
返回的结果集为:
12
42
2
元素3在int2中,所以被过滤掉了,int2中的元素24,不在int1中,所以不会被返回回来。
操作符:Cast
描述:将非泛型的结果皆转成泛型结果集,以支持大部分的标准查询操作符。
如果我们有一个序列是在.net2.0框架上做的,但是,我们又希望用LINQ来操作,此时,我们就可以先将该序列Cast操作后转成IEnumerable<T>.
原型:
publicstaticIEnumerable<TResult>Cast<TResult>(
thisIEnumerablesource
)
借用msdn的例子来说明:
System.Collections.ArrayListfruits=newSystem.Collections.ArrayList();
fruits.Add("apple");
fruits.Add("mango");
IEnumerable<string>query=
fruits.Cast<string>().Select(fruit=>fruit);
foreach(stringfruitinquery)
{
Console.WriteLine(fruit);
}
操作符:OfType
描述:将可以转成某种类型的元素作为结果集输出来,跟Cast一样,OfType的输入序列也是非泛型的IEnumerable
原型:
publicstaticIEnumerable<TResult>OfType<TResult>(
thisIEnumerablesource
)
还是借用msdn的例子:
System.Collections.ArrayListfruits=newSystem.Collections.ArrayList(4);
fruits.Add("Mango");
fruits.Add("Orange");
fruits.Add("Apple");
fruits.Add(3.0);
fruits.Add("Banana");
//ApplyOfType()totheArrayList.
IEnumerable<string>query1=fruits.OfType<string>();
Console.WriteLine("Elementsoftype'string'are:");
foreach(stringfruitinquery1)
{
Console.WriteLine(fruit);
}
ArrayList的签名为:
publicclassArrayList:IList,ICollection,
IEnumerable,ICloneable
它是没有实现IEnumerable<T>,经过OfType后,返回的结果集就支持IEnumerable了。
操作符:AsEnumerable
描述:输入一个IEnumerable<T>序列,返回一个IEnumerable<T>序列。
看到这个描述也许你会觉得很好玩:这不是多此一举吗,没有任何操作,只是为了返回跟输入序列一样的序列。
在稍后的LINQTOSQL我们再来详细讨论这个问题。
原型:
publicstaticIEnumerable<TSource>AsEnumerable<TSource>(
thisIEnumerable<TSource>source
)
操作符:DefaultIfEmpty
原型一:
publicstaticIEnumerable<TSource>DefaultIfEmpty<TSource>(
thisIEnumerable<TSource>source
)
原型二:
publicstaticIEnumerable<TSource>DefaultIfEmpty<TSource>(
thisIEnumerable<TSource>source,
TSourcedefaultValue
)
描述:该操作符主要用来描述,如果序列中的元素为空,该返回什么样的元素。原型一采用默认的对象的构造函数来创建一个空的对象,原型二允许我们定义一个默认的元素。
借用msdn的例子来说明原型二:
classPet
{
publicstringName{get;set;}
publicintAge{get;set;}
}
publicstaticvoidDefaultIfEmptyEx2()
{
PetdefaultPet=newPet{Name="DefaultPet",Age=0};
List<Pet>pets1=
newList<Pet>{newPet{Name="Barley",Age=8},
newPet{Name="Boots",Age=4},
newPet{Name="Whiskers",Age=1}};
foreach(Petpetinpets1.DefaultIfEmpty(defaultPet))
{
Console.WriteLine("Name:{0}",pet.Name);
}
List<Pet>pets2=newList<Pet>();
foreach(Petpetinpets2.DefaultIfEmpty(defaultPet))
{
Console.WriteLine("\nName:{0}",pet.Name);
}
}
输出结果为:
操作符:Range
原型:
publicstaticIEnumerable<int>Range(
intstart,
intcount
)
该操作符返回输入序列的一部分元素
操作符:Repeat
原型:
publicstaticIEnumerable<TResult>Repeat<TResult>(
TResultelement,
intcount
)
对元素element循环count次数
操作符:Empty
原型:
publicstaticIEnumerable<TResult>Empty<TResult>()
描述:这是一个静态方法,但不是一个扩展方法。
IEnumerable<string>strings=Enumerable.Empty<string>();
foreach(stringsinstrings)
Console.WriteLine(s);
Console.WriteLine(strings.Count());
输出结果为:
0
描述:基于匹配键对2个序列的元素进行关联,Join保留了TOuter中元素的顺序,并对于这些元素中的每一个元素,保留TInner中匹配元素的顺序.(来自msdn)
原型:2种
原型一:
Join的参数比较多,需要特别注意。举个例子:
在这个例子中,我们将categories和products通过categories.Id和products.CategoryId进行关联,返回一个新的对象的序列。
原型二略。
操作符:GroupJoin
描述:基于键相等对两个序列的元素进行关联并对结果进行分组.(来自msdn)
原型:
GroupJoin和Join很类似,GroupJoin会对返回的结果给予TOuter的Key进行分组。
对于返回的结果,TOuter中的一个元素可能对应多个TInner元素。
注意:如果TInner中没有TOuter的给定元素的关联元素,则该元素的匹配序列为空,但仍将出现在结果中.
举个例子:
打印出来的结果是:
Food:
Taste
Canidae
Flavor
Toys:
Chuckit
SafeMade
Fruit:
我们可以发现Fruit这个category没有匹配的产品,但是也被打印出来了。
操作符:GroupBy
描述:GroupBy主要用来对输入序列进行分组,并且返回IGrouping<K,T>
原型:GroupBy提供了众多的原型,我们主要关注4个:
原型一:
输出结果:
1:
Taste
Canidae
Flavor
2:
Chuckit
SafeMade
原型一比较简单,主要包含2个参数,一个输入序列,另外一个是selector。
在这个例子中,我们通过对products序列进行按categoryid进行分组,然后按照分组后的key进行排序。
原型二:
原型二为我们多提供了IEqualityComparer参数用以自定义比较方法
这个接口提供了2个方法boolEquals(Tx,Ty)和intGetHashCode(Tobj)2个方法
注意IEqualityComparer是根据Key来比较的,例如,我们可以写个comparer比较器:
thisIEnumerable<TSource>source,
Func<TSource,TKey>keySelector,
Func<TSource,TElement>elementSelector
)
与原型一不一样的是,原型一返回了与输入序列同样的类型元素,原型三可以根据自己的需求,返回所需的元素类型,我们来看个例子:
{
newProduct{ProductId=201,ProductName="Chuckit",CategoryId=2},
newProduct{ProductId=202,ProductName="SafeMade",CategoryId=2},
newProduct{ProductId=101,ProductName="Taste",CategoryId=1},
newProduct{ProductId=102,ProductName="Canidae",CategoryId=1},
newProduct{ProductId=103,ProductName="Flavor",CategoryId=1}
};
varproductList=products.GroupBy(p=>p.CategoryId,p=>new{p.ProductId,p.ProductName}).OrderBy(p=>p.Key);
foreach(varkeyGroupProductsinproductList)
{
Console.WriteLine("Category:"+keyGroupProducts.Key);
foreach(varproductinkeyGroupProducts)
{
Console.WriteLine("{0}-{1}",product.ProductId,product.ProductName);
}
}
我们返回的不再是Product,而是我们新建的一个匿名类型,包含ProductId和ProductName
原型四:
thisIEnumerable<TSource>source,
Func<TSource,TKey>keySelector,
Func<TSource,TElement>elementSelector,
IEqualityComparer<TKey>comparer
)
原型四实际上是原型二和原型三的结合,比较简单,就不举例子了。
操作符:Distinct
描述:Distinct操作符主要用于过滤重复的元素,2个元素相等是通过GetHashCode和Equals来判断的,原型二为我们提供了自己写对等条件的方法
原型:2种
原型一:
thisIEnumerable<TSource>source
)
这个原型很简单,我们借用msdn的例子来说明:
IEnumerable<int>distinctAges=ages.Distinct();
Console.WriteLine("Distinctages:");
foreach(intageindistinctAges)
{
Console.WriteLine(age);
}
输出结果:
Distinctages:
21
46
55
17
重复的46,55被过滤掉了。
原型二:
thisIEnumerable<TSource>source,
IEqualityComparer<TSource>comparer
)
我们先定义一个相等比较器:
{
publicboolEquals(Productx,Producty)
{
if(x==null||y==null)returnfalse;
returnx.ProductId==y.ProductId&&x.CategoryId==y.CategoryId;
}
publicintGetHashCode(Productobj)
{
intproductid=obj.ProductId;
intcategoryid=obj.CategoryId;
returnproductid.GetHashCode()+categoryid.GetHashCode();
}
}
然后,在查询的时候,应用这个比较器:
List<Product>products=newList<Product>
{
newProduct{ProductId=201,ProductName="Chuckit",CategoryId=2},
newProduct{ProductId=201,ProductName="CHUCKIT",CategoryId=2},
newProduct{ProductId=101,ProductName="Taste",CategoryId=1},
newProduct{ProductId=102,ProductName="Canidae",CategoryId=1},
newProduct{ProductId=103,ProductName="Flavor",CategoryId=1}
};
varproductList=products.Distinct(comparer);
foreach(varproductinproductList)
{
Console.WriteLine("{0}:{1}:{2}",product.CategoryId,product.ProductId,product.ProductName);
}
输出结果为:
2:201:Chuckit
1:101:Taste
1:102:Canidae
1:103:Flavor
可以发现,201这个product第二个ProductName为全大写的被过滤掉了,因为根据我们的相等比较器,两个201product是一样的。
操作符:Union
描述:连接2个序列,相同的元素只会保留一个
原型:2种
原型一:
thisIEnumerable<TSource>first,
IEnumerable<TSource>second
)
这也是个很简单的操作符,我们还是来看个简单的例子:
List<int>int2=newList<int>{24,3};
varunitInts=int1.Union(int2);
foreach(varunitIntinunitInts)
{
Console.WriteLine(unitInt);
}
输出结果为:
12
42
3
2
24
int2的3被过滤掉了,因为int1已经存在3这个元素了
原型二为我们提供了相等比较器:
thisIEnumerable<TSource>first,
IEnumerable<TSource>second,
IEqualityComparer<TSource>comparer
)
跟上面的Distinct的原型二类似,我们就不再举例了。
操作符:Intersect
描述:返回2个序列的交集
原型:2种
题外话:看到这里,其实我们就很容易猜出这2种原型是什么了,无非一种是采用默认对等比较的交集操作,另一种是可以自己提供相等比较器的方法
原型一:
thisIEnumerable<TSource>first,
IEnumerable<TSource>second
)
原型二:
thisIEnumerable<TSource>first,
IEnumerable<TSource>second,
IEqualityComparer<TSource>comparer
)
我们举个原型一的例子吧:
List<int>int2=newList<int>{24,3};
varunitInts=int1.Intersect(int2);
foreach(varunitIntinunitInts)
{
Console.WriteLine(unitInt);
}
结果集只会返回3。
操作符:Except
描述:该操作符返回存在于序列1但是不存在序列2的所有元素
原型:2种
原型一:
thisIEnumerable<TSource>first,
IEnumerable<TSource>second
)
原型二:
thisIEnumerable<TSource>first,
IEnumerable<TSource>second,
IEqualityComparer<TSource>comparer
)
我们举个原型一的例子:
List<int>int2=newList<int>{24,3};
varunitInts=int1.Except(int2);
foreach(varunitIntinunitInts)
{
Console.WriteLine(unitInt);
}
返回的结果集为:
12
42
2
元素3在int2中,所以被过滤掉了,int2中的元素24,不在int1中,所以不会被返回回来。
操作符:Cast
描述:将非泛型的结果皆转成泛型结果集,以支持大部分的标准查询操作符。
如果我们有一个序列是在.net2.0框架上做的,但是,我们又希望用LINQ来操作,此时,我们就可以先将该序列Cast操作后转成IEnumerable<T>.
原型:
thisIEnumerablesource
)
借用msdn的例子来说明:
fruits.Add("apple");
fruits.Add("mango");
IEnumerable<string>query=
fruits.Cast<string>().Select(fruit=>fruit);
foreach(stringfruitinquery)
{
Console.WriteLine(fruit);
}
操作符:OfType
描述:将可以转成某种类型的元素作为结果集输出来,跟Cast一样,OfType的输入序列也是非泛型的IEnumerable
原型:
thisIEnumerablesource
)
还是借用msdn的例子:
fruits.Add("Mango");
fruits.Add("Orange");
fruits.Add("Apple");
fruits.Add(3.0);
fruits.Add("Banana");
//ApplyOfType()totheArrayList.
IEnumerable<string>query1=fruits.OfType<string>();
Console.WriteLine("Elementsoftype'string'are:");
foreach(stringfruitinquery1)
{
Console.WriteLine(fruit);
}
ArrayList的签名为:
IEnumerable,ICloneable
它是没有实现IEnumerable<T>,经过OfType后,返回的结果集就支持IEnumerable了。
操作符:AsEnumerable
描述:输入一个IEnumerable<T>序列,返回一个IEnumerable<T>序列。
看到这个描述也许你会觉得很好玩:这不是多此一举吗,没有任何操作,只是为了返回跟输入序列一样的序列。
在稍后的LINQTOSQL我们再来详细讨论这个问题。
原型:
thisIEnumerable<TSource>source
)
操作符:DefaultIfEmpty
原型一:
thisIEnumerable<TSource>source
)
原型二:
thisIEnumerable<TSource>source,
TSourcedefaultValue
)
描述:该操作符主要用来描述,如果序列中的元素为空,该返回什么样的元素。原型一采用默认的对象的构造函数来创建一个空的对象,原型二允许我们定义一个默认的元素。
借用msdn的例子来说明原型二:
{
publicstringName{get;set;}
publicintAge{get;set;}
}
publicstaticvoidDefaultIfEmptyEx2()
{
PetdefaultPet=newPet{Name="DefaultPet",Age=0};
List<Pet>pets1=
newList<Pet>{newPet{Name="Barley",Age=8},
newPet{Name="Boots",Age=4},
newPet{Name="Whiskers",Age=1}};
foreach(Petpetinpets1.DefaultIfEmpty(defaultPet))
{
Console.WriteLine("Name:{0}",pet.Name);
}
List<Pet>pets2=newList<Pet>();
foreach(Petpetinpets2.DefaultIfEmpty(defaultPet))
{
Console.WriteLine("\nName:{0}",pet.Name);
}
}
输出结果为:
Name:Barley
Name:Boots
Name:Whiskers
Name:DefaultPet
第二个序列为空,因此输出了我们事先定义的默认的对象.
操作符:Range
原型:
intstart,
intcount
)
该操作符返回输入序列的一部分元素
操作符:Repeat
原型:
TResultelement,
intcount
)
对元素element循环count次数
操作符:Empty
原型:
描述:这是一个静态方法,但不是一个扩展方法。
foreach(stringsinstrings)
Console.WriteLine(s);
Console.WriteLine(strings.Count());
输出结果为:
0
相关文章推荐
- LINQ之延迟执行标准查询操作符(中)
- LINQ之非延迟执行标准查询操作符(上)
- LINQ之非延迟执行标准查询操作符(下)
- LINQ之延迟执行标准查询操作符(上)
- LINQ 标准的查询操作符 排序 orderby、thenby、Take
- LINQ 标准的查询操作符 分区 Take 、Skip 、TakeWhile 、SkipWhile
- LINQ 的查询执行何时是延迟执行,何时是立即执行,以及查询的复用
- LinQ标准的查询操作符 过滤where,index1,oftype
- Linq to BBJECT之非延时标准查询操作符
- LINQ标准查询操作符学习笔记
- LINQ 标准的查询操作符 排序 orderby、thenby、Take
- LINQ 标准的查询操作符 合计操作符 Count()、Sum()、Min()、Max()、Average()和Aggregate()
- LINQ 的查询执行何时是延迟执行,何时是立即执行,以及查询的复用
- LINQ入门教程之各种标准查询操作符(一)
- LinQ标准的查询操作符 符合的from in子句
- LINQ 的查询执行何时是延迟执行,何时是立即执行,以及查询的复用
- Linq to OBJECT延时标准查询操作符
- LINQ 标准的查询操作符 合计操作符 Count()、Sum()、Min()、Max()、Average()和Aggregate()
- LINQ标准查询操作符
- LinQ标准的查询操作符 排序order,thenby,Take