C# 调用了错误的扩展方法
我在.Net 5 webapi项目中创建了以下扩展方法:C# 调用了错误的扩展方法,c#,generics,C#,Generics,我在.Net 5 webapi项目中创建了以下扩展方法: public static class QueryableExtensions { public static IOrderedQueryable<TSource> Filter<TSource>(this IOrderedQueryable<TSource> query, IEnumerable<string> filter) where TSource : IModel
public static class QueryableExtensions
{
public static IOrderedQueryable<TSource> Filter<TSource>(this IOrderedQueryable<TSource> query, IEnumerable<string> filter) where TSource : IModel
{
throw new NotImplementedException();
}
public static IOrderedQueryable<ApplicationUser> Filter(this IOrderedQueryable<ApplicationUser> query, IEnumerable<string> filter)
{
return query
.Where(x => filter.Any(str => !string.IsNullOrEmpty(x.Email) && x.Email.Contains(str, StringComparison.CurrentCultureIgnoreCase)))
.OrderBy(x => x.Id);
}
}
公共静态类QueryableExtensions
{
公共静态IOrderedQueryable筛选器(此IOrderedQueryable查询,IEnumerable筛选器),其中TSource:IModel
{
抛出新的NotImplementedException();
}
公共静态IOrderedQueryable筛选器(此IOrderedQueryable查询,IEnumerable筛选器)
{
返回查询
.Where(x=>filter.Any(str=>!string.IsNullOrEmpty(x.Email)和&x.Email.Contains(str,StringComparison.CurrentCultureIgnoreCase)))
.OrderBy(x=>x.Id);
}
}
通用的只是一个“占位符”。我在服务存储库模式中的一些服务类中使用这些方法
基本服务类别:
public class DataServiceBase<T> : IDataService<T> where T : class, IModel, new()
{
public IValidationDictionary ValidationDictionary { get; }
protected readonly IRepository<T> Repo;
public DataServiceBase(IRepository<T> repo, IValidationDictionary validationDictionary)
{
Repo = repo;
ValidationDictionary = validationDictionary;
}
public virtual IOrderedQueryable<T> Read(ApplicationContext applicationContext)
{
return Repo.Read().OrderBy(x => x.Id);
}
public virtual IOrderedQueryable<T> Read(ApplicationContext applicationContext, ReadListSettings readListSettings)
{
var query = Read(applicationContext);
if (readListSettings.Filter != null)
{
// HERE THE EXTENSIONS METHOD IS USED
query = query.Filter(readListSettings.Filter.Process());
// HERE THE EXTENSIONS METHOD IS USED
}
return query;
}
}
公共类DataServiceBase:IDataService,其中T:class,IModel,new()
{
公共IValidationDictionary验证字典{get;}
受保护的只读电子回购;
公共数据服务库(IRepository repo、IValidationDictionary validationDictionary)
{
回购=回购;
ValidationDictionary=ValidationDictionary;
}
公共虚拟IOrderedQueryable读取(ApplicationContext ApplicationContext)
{
返回Repo.Read().OrderBy(x=>x.Id);
}
公共虚拟IOrderedQueryable读取(ApplicationContext ApplicationContext,ReadListSettings ReadListSettings)
{
var query=Read(applicationContext);
if(readListSettings.Filter!=null)
{
//这里使用扩展方法
query=query.Filter(readListSettings.Filter.Process());
//这里使用扩展方法
}
返回查询;
}
}
还有一个具体的例子:
public partial class ApplicationUserService : DataServiceBase<ApplicationUser>
{
public ApplicationUserService(
IRepository<ApplicationUser> repo,
IValidationDictionary validationDictionary
) : base(repo, validationDictionary) {}
public override IOrderedQueryable<ApplicationUser> Read(ApplicationContext applicationContext)
{
return Repo
.Read()
.Include(x => x.User2UserGroups)
.ThenInclude(x => x.UserGroup)
.ThenInclude(x => x.Tenant)
.OrderBy(x => x.Email);
}
}
公共部分类ApplicationUserService:DataServiceBase
{
公共应用服务(
i推定回购,
IValidationDictionary验证字典
):base(repo,validationDictionary){}
公共覆盖IOrderedQueryable读取(ApplicationContext ApplicationContext)
{
回购回报
.读()
.Include(x=>x.User2UserGroups)
.ThenInclude(x=>x.UserGroup)
.然后包括(x=>x.Tenant)
.OrderBy(x=>x.Email);
}
}
我希望在调用ApplicationUserService.Read(applicationcontext,readlistsettings)时调用extensionmethod的特定版本。我检查了类型,泛型方法得到了正确的类作为其TSource
我尝试将以下内容添加到AppUserService中,但仍然调用了TSource版本
public override IOrderedQueryable<ApplicationUser> Read(ApplicationContext applicationContext, ReadListSettings readListSettings)
{
return base.Read(applicationContext, readListSettings);
}
public override IOrderedQueryable Read(ApplicationContext ApplicationContext,ReadListSettings ReadListSettings)
{
返回base.Read(applicationContext,readListSettings);
}
有什么建议吗?扩展方法与多态性无关。 考虑到这些模型和设置:
public interface IModel
{
public int Id { get; set; }
}
public class ApplicationUser : IModel
{
public int Id { get; set; }
public string Email { get; set; }
}
public class ReadListSettings
{
public IEnumerable<string> Filter { get; set; }
}
公共接口IModel
{
公共int Id{get;set;}
}
公共类应用程序用户:IModel
{
公共int Id{get;set;}
公共字符串电子邮件{get;set;}
}
公共类ReadListSettings
{
公共IEnumerable筛选器{get;set;}
}
您的自定义筛选可以这样实现:
public abstract class DataServiceBase<T>
where T : IModel
{
public IOrderedQueryable<T> Read()
{
// gets queryable from repository somehow
return Enumerable.Empty<T>().AsQueryable().OrderBy(x => x.Id);
}
public IOrderedQueryable<T> Read(ReadListSettings readListSettings)
{
var query = Read();
if (readListSettings.Filter != null)
{
// use custom filtering in descendatns here
query = Filter(query, readListSettings.Filter);
}
return query;
}
protected virtual IOrderedQueryable<T> Filter(IOrderedQueryable<T> query, IEnumerable<string> filter) => query;
}
public partial class ApplicationUserService : DataServiceBase<ApplicationUser>
{
protected override IOrderedQueryable<ApplicationUser> Filter(IOrderedQueryable<ApplicationUser> query, IEnumerable<string> filter)
{
return query
.Where(x => filter.Any(str => !string.IsNullOrEmpty(x.Email) && x.Email.Contains(str, StringComparison.CurrentCultureIgnoreCase)))
.OrderBy(x => x.Id);
}
}
公共抽象类DataServiceBase
T:IModel在哪里
{
公共IOrderedQueryable Read()
{
//以某种方式从存储库获取可查询信息
返回可枚举的.Empty().AsQueryable().OrderBy(x=>x.Id);
}
公共IOrderedQueryable读取(ReadListSettings ReadListSettings)
{
var query=Read();
if(readListSettings.Filter!=null)
{
//在DenaRatns中使用自定义筛选
query=Filter(查询,readListSettings.Filter);
}
返回查询;
}
受保护的虚拟IOrderedQueryable筛选器(IOrderedQueryable查询,IEnumerable筛选器)=>查询;
}
公共部分类ApplicationUserService:DataServiceBase
{
受保护的覆盖IOrderedQueryable筛选器(IOrderedQueryable查询,IEnumerable筛选器)
{
返回查询
.Where(x=>filter.Any(str=>!string.IsNullOrEmpty(x.Email)和&x.Email.Contains(str,StringComparison.CurrentCultureIgnoreCase)))
.OrderBy(x=>x.Id);
}
}
(我简化了您的类型,只留下了相关代码)扩展方法与多态性无关。 考虑到这些模型和设置:
public interface IModel
{
public int Id { get; set; }
}
public class ApplicationUser : IModel
{
public int Id { get; set; }
public string Email { get; set; }
}
public class ReadListSettings
{
public IEnumerable<string> Filter { get; set; }
}
公共接口IModel
{
公共int Id{get;set;}
}
公共类应用程序用户:IModel
{
公共int Id{get;set;}
公共字符串电子邮件{get;set;}
}
公共类ReadListSettings
{
公共IEnumerable筛选器{get;set;}
}
您的自定义筛选可以这样实现:
public abstract class DataServiceBase<T>
where T : IModel
{
public IOrderedQueryable<T> Read()
{
// gets queryable from repository somehow
return Enumerable.Empty<T>().AsQueryable().OrderBy(x => x.Id);
}
public IOrderedQueryable<T> Read(ReadListSettings readListSettings)
{
var query = Read();
if (readListSettings.Filter != null)
{
// use custom filtering in descendatns here
query = Filter(query, readListSettings.Filter);
}
return query;
}
protected virtual IOrderedQueryable<T> Filter(IOrderedQueryable<T> query, IEnumerable<string> filter) => query;
}
public partial class ApplicationUserService : DataServiceBase<ApplicationUser>
{
protected override IOrderedQueryable<ApplicationUser> Filter(IOrderedQueryable<ApplicationUser> query, IEnumerable<string> filter)
{
return query
.Where(x => filter.Any(str => !string.IsNullOrEmpty(x.Email) && x.Email.Contains(str, StringComparison.CurrentCultureIgnoreCase)))
.OrderBy(x => x.Id);
}
}
公共抽象类DataServiceBase
T:IModel在哪里
{
公共IOrderedQueryable Read()
{
//以某种方式从存储库获取可查询信息
返回可枚举的.Empty().AsQueryable().OrderBy(x=>x.Id);
}
公共IOrderedQueryable读取(ReadListSettings ReadListSettings)
{
var query=Read();
if(readListSettings.Filter!=null)
{
//在DenaRatns中使用自定义筛选
query=Filter(查询,readListSettings.Filter);
}
返回查询;
}
受保护的虚拟IOrderedQueryable筛选器(IOrderedQueryable查询,IEnumerable筛选器)=>查询;
}
公共部分类ApplicationUserService:DataServiceBase
{
受保护的覆盖IOrderedQueryable筛选器(IOrderedQueryable查询,IEnumerable筛选器)
{
返回查询
.Where(x=>filter.Any(str=>!string.IsNullOrEmpty(