为什么';return';和';收益率回报率;在本例中具有相同的行为
本文关键字:return 收益率 回报率 为什么 | 更新日期: 2023-09-27 18:25:30
我正在阅读这篇关于流利风格语法的文章,并尝试了这个例子。我注意到,当我将YoungDogs()
和HerdingDogs()
方法体转换为LINQ表达式时,yield return
被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);
}
}
此dogs.Where(d => d.Age < 10);
声明了一个序列,当调用YoungDogs
时将返回该序列。将返回的是序列的声明,而不是"通过过滤器"的狗。只有当您请求时,您才会从dogs
集合中获得实际对象。
在后台,Where
封装了对yield return
的调用,通过该调用,dogs
中传递谓词的项一个接一个地返回。发生这种情况的原因如下:
// That declares the sequence, you want to get.
// In dogsWithAgeLessThanTen you don't have actaully any dog.
var dogsWithAgeLessThanTen = dogs.Where(d => d.Age < 10);
// Now you request the above query to be executed, that's called lazy loading.
// Here you get one after the other the dogs that have age less than 10.
// The Enumerator you get from the dogsWithAgeLessThanTen returns your data
// through a yield return statement.
foreach(var dog in dogsWithAgeLessThanTen)
{
}
以上内容相同,关于结果,将返回以下内容:
public static IEnumerable<Dog> YoungDogs(this IEnumerable<Dog> dogs)
{
foreach (Dog d in dogs)
if (d.Age < 10)
yield return d;
}
var dogsWithAgeLessThanTen = dogs.YoungDogs();
foreach(var dog in dogsWithAgeLessThanTen)
{
}