[英]c# constraints ignored in extension with generic type
public interface ICardEntity { ... }
public class Card : ICardEntity { ... }
public static class MyExtensions
{
public static List<T> ToList<T>(this IQueryable<T> query) where T : ICardEntity
{ ... }
}
// DbContext
public class ApplicationDbContext : DbContext
{
public DbSet<Card> Cards { get; set; }
}
.....
var list = dbContext.Cards
.ToList(); // -- OK, my extension is called
var list2 = dbContext.Cards
.GroupBy(t => new { Type = t.Type})
.ToList(); // -- Compile error. Why not System.Linq.Enumerable.ToList() is called?
我希望僅為IQueryable <ICardEntity>調用我的ToList,而不是為IGrouping << anonymous type:short H>,Card>調用。 為什么約束“哪里T:ICardEntity”不起作用?
錯誤信息:
類型'System.Linq.IGrouping << anonymous type:short H>,Nucleo.Tests.Models.Card>'不能在泛型類型或方法'MyExtensions.ToList(IQueryable)'中用作類型參數'T'。 從'System.Linq.IGrouping <,Nucleo.Tests.Models.Card>'到'ICardEntity'沒有隱式引用轉換。
在C#中, 通用約束沒有重載 。 您可以重載參數計數和參數類型,但不能重復返回值,通用約束等等。這就是全部。
在重載解析期間,編譯器只需要使用ToList(),因為方法的名稱以及參數的數量和類型匹配。 它之后會驗證通用約束,但此時它已經是錯誤,而不是過載分辨率候選丟失。 我不知道如何以更易讀的方式表達它。 我希望你明白。
經過思考 -
如果您習慣使用C ++及其模板,那么它不是C ++,並且沒有SFINAE可以讓它像你想象的那樣工作。
所有'重載解析'和'方法匹配/查找/等'必須遵循CLS / CLR的規則,所有語言的整個平台,如VB,C#,F3等。它是CLS / CLR定義如何查找方法,如何解決重載候選,等等。 而且,遺憾的是,重載超出泛型類型參數約束,它不包含在規范中。 IIRC將其添加到規范中會在整個平台上產生幾個問題(IIRC,類型和方法解析性能),所以沒有添加..但這就是我記得的。 重要的是,它不在語言和運行時平台規范中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.