我正在為使用物體框架的類添加單元測驗。我在此基礎上添加了測驗替身,并成功運行了一些測驗。但是,當我開始針對依賴于DbSet<T>.RemoveRange(IEnumerable<T>). 我將以下覆寫添加到TestDbSet<T>(源自DbSet<T>; 來自鏈接):
public override IEnumerable<TEntity> RemoveRange(IEnumerable<TEntity> entities)
{
foreach (var item in entities)
{
Data.Remove(item);
yield return item;
}
}
但是,當我有一個TestDbSet<T>分配給DbSet<T>變數的實體并嘗試呼叫RemoveRange時,它不會運行我上面寫的覆寫——它似乎正在使用基類的實作。
這讓我有點困惑。我確認該實體實際上是 a TestDbSet<T>,當然它是,因為其他方法覆寫正在作業。所以我試著思考這個方法有什么不同,而且,它是唯一的一個迭代器方法(yield return),所以我重寫了它:
public override IEnumerable<TEntity> RemoveRange(IEnumerable<TEntity> entities)
{
entities = entities.ToList();
foreach (var item in entities)
{
Data.Remove(item);
}
return entities;
}
......突然它起作用了?現在,當我呼叫RemoveRange(DbSet<T>實際上是 a TestDbSet<T>)時,它呼叫TestDbSet<T>.RemoveRange而不是DbSet<T>.RemoveRange.
我試過來回切換它。我已經確認,ToList()單獨并不能解決它。只有避免yield return似乎可以解決它。
有人可以解釋是什么原因造成的嗎?使用迭代器方法會改變方法的宣告還是什么?如果是這樣,那是如何允許/兼容的override?
uj5u.com熱心網友回復:
您很可能沒有列舉RemoveRange. 迭代器方法(帶有yield return/的方法yield break)是特殊的 - 它們是“惰性的”,并且當您呼叫該方法時,它們中的代碼不會正確執行,但只有在列舉回傳值時才會執行。例如:
public static void Main() {
Test();
}
static IEnumerable<int> Test() {
Console.WriteLine("Got in");
yield return 1;
Console.WriteLine("Returned 1");
}
這不會向控制臺列印任何內容,因為Test從不列舉回傳值。另一方面:
public static void Main() {
Test().ToList();
}
static IEnumerable<int> Test() {
Console.WriteLine("Got in");
yield return 1;
Console.WriteLine("Returned 1");
}
將列印兩個陳述句,因為我們用 列舉結果ToList()。
這導致我們不能在您的情況下使用迭代器方法這一事實 -RemoveRange這不是一個有效的候選者。是的,它回傳IEnumerable,但是這個函式的主要目的是洗掉物體,而回傳值是一種可選的副作用,你不能指望呼叫者總是列舉它(在大多數情況下,回傳值將被完全忽略) .
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/526050.html
上一篇:僅從每個組中選擇第一行。物體框架
