我正在努力理解這行代碼,但我并沒有擺脫它。
指令如下
var targetHandles = target.Where(t => true);
這是在具有這些簽名的函式內
public static void Merge<T>(ObservableCollection<T> target, ObservableCollection<T> source) where T : DtoBase
預先感謝您的回答
瑞克
uj5u.com熱心網友回復:
我不知道你的問題是否僅僅是在WhereLINQ的,還是在where T: DtoBase,所以我將討論這兩個
在泛型方法中的位置
public static void Merge<T>(ObservableCollection<T> target,
ObservableCollection<T> source)
where T : DtoBase
該<T>方法的標識后Merget<T>,告訴我們這是一個generic method,這意味著你可以用各種類呼叫它,只要類符合where條件:
where T : DtoBase
所以你可以用任何類 T 呼叫這個方法,只要這個類是(派生自)DtoBase。
例子:
class DtoBase {...};
class Derived : DtoBase {...};
ObservableCollection<DtoBase> myBases = ...
ObservableCollection<DtoBase> yourBases = ...
ObservableCollection<Derived> myDeriveds = ...
ObservableCollection<Derived> yourDeriveds = ...
現在您可以呼叫 method Merge,并將每個 Occurence ot 替換為T匹配的任何內容where T : DtoBase。所以以下都是有效的:
Merge(myBases, yourBases);
Merge(myBases, myBases);
Merge(myDeriveds, yourDeriveds);
Merge(myBases, myDeriveds);
以下不會編譯:
Merge(myBases, 4); // integer 4 is not a DtoBase
Merge("Hello", myBases); // string is not a DtoBase
在 LINQ 陳述句中的位置
var targetHandles = target.Where(t => true);
在t本宣告無關的通用方法做與T。
如果您查看Enumerable.Where的定義,您會發現它是一個通用擴展方法。
public static IEnumerable<TSource> Where<TSource> (
this IEnumerable<TSource> source,
Func<TSource,bool> predicate);
上面討論了泛型: Where has a type TSource,與T我們之前討論的類似:無論您看到TSource什么,都應該將其替換為相同的實際型別。
We also see the keyword this in front of the first parameter. This means that it is an extension method: you can put the first parameter in front of the method, like this:
IEnumerable<Product> products = ...
IEnumerable<Product> cheapProducts = products.Where(product => product.Price < 1);
This is the same as:
IEnumerable<Product> cheapProducts = Enumerable<Product>.Where(products,
product => product.Price < 1);
So extension method is just some fancy syntactic sugar. It makes it look as if it is a method of Product.
Now the fun part: the product in product => product.Price < 1. product is just an identifier with a well chosen name. I could also have written:
.Where(t => t.Price < 1);
the t => t.Price < 1 is called a lambda expression. It is some shorthand for a function definition: we create a method with input parameter t, which returns t.price < 1. The type of t can be found in the generic:
public static IEnumerable<TSource> Where<TSource> (
this IEnumerable<TSource> source,
Func<TSource,bool> predicate);
In my example TSource was a Product, so the first parameter should be IEnumerable<Product>. The return value is also IEnumerable<TSource>.
IEnumerable<Product> products = ...
IEnumerable<Product> cheapProducts = products.Where(...);
predicate is a Func<TSource, bool>. This means: any function, with input TSource (which is in our case a Product), that returns a bool. So if you see somewhere:
Func<int, string, DateTime, Point>
Then it means: any method with three input parameters of type int, string, DateTime (in this order), which returns a Point:
Point MyFunct(int i, string txt, DateTime date) {...}
We've seen that the lambda expression t => t.Price < 1 is a method that takes a Product t as input parameter and returns the value of t.Price < 1, which obviously is a Boolean. Hence, this lambda expression matches Func<TSource,bool>.
IEnumerable<Product> cheapProducts = products.Where(product => product.Price < 1);
So what does this do? It takes every product from the sequence of products, and puts this in the function product => product.Price < 1. In other words: from every product in the sequence of Products, it calculates the Boolean product.Price < 1. It it is true, then we keep it, if not, we don't use it in the sequence returned by the Where.
The effect is, that Where(product => product.Price < 1) returns the sequence of all Products with a value for property Price that is less than 1.
Back to your question
Your Where is a rather strange one.
IEnumerable<Target> targets = ...
targets.Where(t => true);
We know that targets is a sequence of type Target. Hence, we know that the predicate is a method that takes as input one Target, and returns a bool:
bool Predicate(Target t) { return true}
Well, it does return a boolean. In fact, it always returns the same boolean, it doesn't even look at the input parameter t, it always returns true.
Where(t => true) is similar to the following:
foreach(Target target in targets)
{
if (true) return target;
}
Well, this doesn't do a lot: it returns the complete input sequence:
IEnumerable<Target> targets = ...
var result = targets.Where(t => true);
We know that result has the same elements, in the same order as targets. The statement is not very useful.
Final remark
Whenever you have to define your own identifiers in LINQ statements, try to use plural nouns to identify sequences, use singular nouns to identify elements of the sequences. Try to avoid meaningless identifiers as t =>.
typing less characters is not a good excuse for choosing bad identifiers!
IEnumerable<Customer> customers = ...
IEnumerable<Order> orders = ...
var customersWithTheirOrders = customer.GroupJoin(orders,
customer => customer.Id, // from every Customer take the primary key
order => order.CustomerId, // from every Order take the foreign key
(customer, ordersOfThisCustomer) => new
{
Id = customer.Id,
Name = customer.Name,
Address = customer.Address,
Orders = ordersOfThisCustomer.Select(order => new
{
Date = order.Date,
Total = order.Total,
})
.ToList(),
})
This is a very big LINQ. You might not be familiar with GroupJoin, but because I used plural and singular nouns, it is not very difficult to read:
換句話說:我們有一系列客戶和一系列訂單。We GroupJoin 客戶和訂單。這意味著,我們從每個客戶中獲取 ID,從每個訂單中獲取 CustomerId。我們嘗試匹配它們。從每個擁有零個或多個訂單的客戶那里,我們制作一個新物件。
這個新物件包含客戶的 ID,以及他的姓名和地址。從該客戶的訂單序列中的每個訂單中,我們創建一個新物件。這個新物件包含訂單的日期和總計。
因為我使用了復數和單數名詞,所以這段文字描述與 LINQ 非常吻合。你不必知道什么t和x有。Customer并且OrdersOfThisCustomer更容易理解它們代表什么。
uj5u.com熱心網友回復:
運算式source.Where(x => true)將回傳一個IEnumerable包含所有專案中source,無論每個專案的價值。這是因為true是整個謂詞,它確定應過濾哪些專案,并且true始終為true。
在大多數情況下,這樣的謂詞將是項的函式(例如x > 3),但并非必須如此。
因此,target.Where(t => true)回傳IEnumerable<T>包含 中所有專案的target。這樣,就創建了一個可以單獨使用(不影響target)的單獨集合。
var targetHandles = target;,另一方面,會創建對 的參考target。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/350320.html
上一篇:DIAMOND(DD)重新定義DeFi,釋放新經濟范式紅利
下一篇:帶有嵌套Any()翻譯錯誤的查詢
