[英]Reasons to specify generic types in LINQ extension methods
只是出於好奇:
許多 LINQ 擴展方法以通用和非通用變體的形式存在,例如Any
和Any<>
、 Where
和Where<>
等。編寫我的查詢時,我通常使用非通用變體,它工作正常。
什么情況下必須使用泛型方法?
- - 編輯 - -
PS:我知道內部只調用泛型方法並且編譯器在編譯期間嘗試解析泛型括號<>
的內容。 我的問題是什么情況下必須明確提供類型而不依賴於編譯器的直覺?
總是。 C# 編譯器足夠聰明,可以根據參數推斷方法的類型。 當類型是匿名的,因此沒有名稱時,這一點很重要。
obj.SomeMethod(123); //these calls are the same
obj.SomeMethod<int>(123);
obj.SomeMethod(new { foo = 123 }); //what type would I write here?!
編輯:要清楚,您總是在調用泛型方法。 它只是看起來像一個非泛型方法,因為編譯器和 Intellisense 很聰明。
編輯:對於您更新的問題,如果您想使用不是您傳遞的 object 類型的類型,您需要具體說明。 有兩種這樣的情況:
如果參數實現了一個接口,並且你想對該接口進行操作,而不是具體類型,那么你應該指定接口:
obj.DoSomething<IEnumerable<Foo>>( new List<Foo>() );
如果參數可以隱式轉換為另一種類型,並且您想使用第二種類型,那么您應該指定它:
obj.DoSomethingElse<long> ( 123 ); //123 is actually an int, but convertible to long
另一方面,如果您需要強制轉換來進行轉換(或者您仍然插入一個),那么您不需要指定:
obj.DoYetAnotherThing( (Transformed)new MyThing() ); // calls DoYetAnotherThing<Transformed>
我今天遇到的一個例子:
ObjectSet<User> users = context.Users;
var usersThatMatch = criteria.Aggregate(users, (u, c) => u.Where(c));
上面的代碼不起作用,因為 .Where 方法不返回ObjectSet<User>
。 您可以通過以下兩種方式之一解決此問題。 我可以在用戶上調用.AsQueryable()
,以確保它被強類型化為 IQueryable,或者我可以將特定類型 arguments 傳遞給 Aggregate 方法:
criteria.Aggregate<Func<User, bool>, IEnumerable<User>>(
PersonSet, (u, c) => u.Where(c));
另外兩個更常見的示例是Cast
和OfType
方法,它們無法推斷出您想要什么類型,並且在許多情況下,首先在非泛型集合上調用。
通常,設計 LINQ 方法的人會竭盡全力避免在這些泛型方法中使用顯式類型,而且大多數情況下您不需要。 我會說最好知道這是一種選擇,但除非您認為有必要,否則請避免這樣做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.