3
我正在讀這個article about fluent-style syntax,我試過這個例子。我注意到,當我將YoungDogs()
和HerdingDogs()
方法體轉換爲LINQ表達式時,yield return
被替換爲return
,但該方法的行爲保持不變。爲什麼在本例中'return'和'yield return'具有相同的行爲?
爲什麼將方法更改爲LINQ表達式會改變數據返回方式的行爲?
這是如在文章中概述的最初的例子:
public static IEnumerable<Dog> YoungDogs(this IEnumerable<Dog> dogs)
{
foreach (Dog d in dogs)
if (d.Age < 10)
yield return d;
}
public static IEnumerable<Dog> HerdingDogs(this IEnumerable<Dog> dogs)
{
foreach (Dog d in dogs)
if ((d.Breed == Breed.BorderCollie) ||
(d.Breed == Breed.Collie) ||
(d.Breed == Breed.Sheltie))
yield return d;
}
這是完整的程序與改變的方法:
class Program
{
static void Main(string[] args)
{
foreach (Dog d in AllMyDogs().YoungDogs().HerdingDogs())
{
Console.WriteLine(d.ToString());
if (d.Breed == Breed.JackRussell)
break;
}
Console.ReadLine();
}
private static IEnumerable<Dog> AllMyDogs()
{
yield return new Dog("Kirby", Breed.BorderCollie, 14);
yield return new Dog("Jack", Breed.JackRussell, 15);
yield return new Dog("Ruby", Breed.Mutt, 4);
yield return new Dog("Lassie", Breed.Collie, 19);
yield return new Dog("Shep", Breed.Collie, 2);
yield return new Dog("Foofoo", Breed.Sheltie, 8);
yield return new Dog("Pongo", Breed.Dalmatian, 4);
yield return new Dog("Rooster", Breed.WestHighlandTerrier, 1);
}
}
static class DogFilters
{
public static IEnumerable<Dog> YoungDogs(this IEnumerable<Dog> dogs)
{
return dogs.Where(d => d.Age < 10);
}
public static IEnumerable<Dog> HerdingDogs(this IEnumerable<Dog> dogs)
{
return dogs.Where(d => (d.Breed == Breed.BorderCollie) ||
(d.Breed == Breed.Collie) ||
(d.Breed == Breed.Sheltie));
}
}
public enum Breed
{
BorderCollie,
Collie,
Sheltie,
JackRussell,
Mutt,
Dalmatian,
WestHighlandTerrier
}
public class Dog
{
public string Name { get; set; }
public Breed Breed { get; set; }
public int Age { get; set; }
public Dog(string name, Breed breed, int age)
{
Name = name;
Breed = breed;
Age = age;
}
public bool TryBark(out string barkSound)
{
bool success = false;
barkSound = "";
if (Age <= 10)
{
success = true;
barkSound = "Woof";
}
return success;
}
public string Bark()
{
string barkSound;
if (!TryBark(out barkSound))
throw new Exception("This dog can't bark");
return barkSound;
}
public override string ToString()
{
return string.Format("{0} <{1}>, age {2}", Name, Breed.ToString(), Age);
}
}
的'Where'方法封裝了'yield'。 – jmcilhinney 2014-10-03 11:38:09
查看Jon Skeet的edulinq系列。他很好地解釋了Linq如何實施的細節。以下是「Where」部分的鏈接http://edulinq.googlecode.com/hg/posts/02-Where.html。 – juharr 2014-10-03 11:46:57
@jmcilhinney不是。你可以使用'Where'並仍然使用'yield return',你可以*不使用'Where'並仍然使用'return'。 – Rawling 2014-10-03 12:23:24