c# 7 当对方法参数使用泛型时,我得到 The constraints for type parameter 'U' of method must match the constraints for the interface
c# 7 when using generics for method parameter I get The constraints for type parameter 'U' of method must match the constraints for the interface
我正在尝试创建一个接口和一个具体实现,其中接口是泛型类型,其中一个方法具有泛型参数。
我想保留 GetPagedList 方法参数 resourceParams 的通用性,这样我就可以为接口的不同实现传入不同的 resourceParams 对象。
当使用下面显示的代码时,出现错误;
The constraints for type parameter 'U' of method 'ShippingServicesRepository.GetPagedList(U)' must match the constraints for the type parameter 'U' of interface method IBaseRepository.GetPagedList(U). Consider using an explicit interface implementation instead
这是我的界面;
public interface IBaseRepository<T>
{
bool Save();
bool Exists(int recordId);
bool MarkForDeletion(int recordId);
PagedList<T> GetPagedList<U>(U resourceParams) where U : class;
T Get(int id);
void Add(T record);
void Update(T record);
}
这是我的实现;
public class ShippingServicesRepository<T> : IBaseRepository<T>
{
// /--- GetPagedList is what is throwing the error
// |
public PagedList<T> GetPagedList<U> (U resourceParams) where U : ShippingServicesResourceParameters
{
try
{
var collectionBeforePaging =
_manifestContext.ShippingServices
.ApplySort(resourceParams.OrderBy, _propertyMappingService.GetPropertyMapping<ShippingServicesDto, ShippingServices>());
if (!string.IsNullOrEmpty(resourceParams.SearchQuery))
{
var searchQueryForWhereClause = resourceParams.SearchQuery.Trim().ToLowerInvariant();
collectionBeforePaging = collectionBeforePaging
.Where(a => a.ReferenceId.ToLowerInvariant().Contains(searchQueryForWhereClause));
}
collectionBeforePaging = collectionBeforePaging
.Where(d => d.DeleteFlag == resourceParams.DeleteFlag);
return (dynamic)PagedList<ShippingServices>.Create(collectionBeforePaging,
resourceParams.PageNumber,
resourceParams.PageSize);
}
catch (Exception)
{
_logger.LogError(500, "ShippingServices Filter [{FILTER}]", resourceParams);
throw;
}
}
public void Add(T record)
{
...
}
public bool Exists(int recordId)
{
...
}
public T Get(int id)
{
...
}
public bool MarkForDeletion(int recordId)
{
...
}
public bool Save()
{
...
}
public void Update(T record)
{
...
}
}
这是我的 ShippingServicesResourceParameters class
public class ShippingServicesResourceParameters : BaseResourceParameters
{
public string FileName { get; set; }
}
这里是ShippingServicesResourceParameters
继承的BaseResourceParametersclass
public class BaseResourceParameters
{
private int _pageSize;
public int PageNumber { get; set; } = 1;
public int PageSize
{
get
{
return _pageSize;
}
set
{
_pageSize = (value > MaxPageSize) ? MaxPageSize : value;
if (value == 0)
{
_pageSize = 10; // set a default size
}
}
}
public int MaxPageSize { get; set; } = 20;
public bool DeleteFlag { get; set; }
public string SearchQuery { get; set; }
public string OrderBy { get; set; } = "Id";
public string Fields { get; set; }
}
如果我没有在具体实现中的方法签名中添加 "where U : ShippingServicesResourceParameters" 并且在接口中添加 "where U : class" ,我会在第一次使用时出现 "Cannot convert from Method Group to String..." 错误resourceParams变量在具体实现中。 (在“.ApplySort(resourceParams.OrderBy”)
我在这里错过了什么?
让我们做你首先应该做的事情并制作一个演示问题的最小程序:
interface I
{
void M<U>(U u) where U : class;
}
class D
{
public void O() {}
}
class C : I
{
public void M<U>(U u) where U : D
{
u.O();
}
}
这是一个错误,因为 C 没有实现 I。它没有实现 I,因为:
I i = new C();
i.M<Giraffe>(new Giraffe());
现在我们有一只长颈鹿传递给 C.M<Giraffe>(Giraffe)
但 C.M<U>
要求 U 是 D。所以这是非法的。
我们不能这样修复它:
public void M<U>(U u) where U : class
{
u.O();
}
因为现在我们可以 D.O()
调用 Giraffe 类型的接收器。
因此我们必须这样修复它:
interface I
{
void M<U>(U u) where U : D;
}
class D
{
public void O() {}
}
class C : I
{
public void M<U>(U u) where U : D
{
u.O();
}
}
现在我们都很好。
您需要使实现约束与接口约束相匹配,就像您需要满足接口强加的所有其他要求一样。 接口是契约。你必须履行讨价还价的义务。
我注意到错误消息是这样说的:您必须匹配约束条件,但您没有这样做。注意错误信息;大多数时候他们会告诉你哪里出了问题。
我正在尝试创建一个接口和一个具体实现,其中接口是泛型类型,其中一个方法具有泛型参数。
我想保留 GetPagedList 方法参数 resourceParams 的通用性,这样我就可以为接口的不同实现传入不同的 resourceParams 对象。
当使用下面显示的代码时,出现错误;
The constraints for type parameter 'U' of method 'ShippingServicesRepository.GetPagedList(U)' must match the constraints for the type parameter 'U' of interface method IBaseRepository.GetPagedList(U). Consider using an explicit interface implementation instead
这是我的界面;
public interface IBaseRepository<T>
{
bool Save();
bool Exists(int recordId);
bool MarkForDeletion(int recordId);
PagedList<T> GetPagedList<U>(U resourceParams) where U : class;
T Get(int id);
void Add(T record);
void Update(T record);
}
这是我的实现;
public class ShippingServicesRepository<T> : IBaseRepository<T>
{
// /--- GetPagedList is what is throwing the error
// |
public PagedList<T> GetPagedList<U> (U resourceParams) where U : ShippingServicesResourceParameters
{
try
{
var collectionBeforePaging =
_manifestContext.ShippingServices
.ApplySort(resourceParams.OrderBy, _propertyMappingService.GetPropertyMapping<ShippingServicesDto, ShippingServices>());
if (!string.IsNullOrEmpty(resourceParams.SearchQuery))
{
var searchQueryForWhereClause = resourceParams.SearchQuery.Trim().ToLowerInvariant();
collectionBeforePaging = collectionBeforePaging
.Where(a => a.ReferenceId.ToLowerInvariant().Contains(searchQueryForWhereClause));
}
collectionBeforePaging = collectionBeforePaging
.Where(d => d.DeleteFlag == resourceParams.DeleteFlag);
return (dynamic)PagedList<ShippingServices>.Create(collectionBeforePaging,
resourceParams.PageNumber,
resourceParams.PageSize);
}
catch (Exception)
{
_logger.LogError(500, "ShippingServices Filter [{FILTER}]", resourceParams);
throw;
}
}
public void Add(T record)
{
...
}
public bool Exists(int recordId)
{
...
}
public T Get(int id)
{
...
}
public bool MarkForDeletion(int recordId)
{
...
}
public bool Save()
{
...
}
public void Update(T record)
{
...
}
}
这是我的 ShippingServicesResourceParameters class
public class ShippingServicesResourceParameters : BaseResourceParameters
{
public string FileName { get; set; }
}
这里是ShippingServicesResourceParameters
继承的BaseResourceParametersclasspublic class BaseResourceParameters
{
private int _pageSize;
public int PageNumber { get; set; } = 1;
public int PageSize
{
get
{
return _pageSize;
}
set
{
_pageSize = (value > MaxPageSize) ? MaxPageSize : value;
if (value == 0)
{
_pageSize = 10; // set a default size
}
}
}
public int MaxPageSize { get; set; } = 20;
public bool DeleteFlag { get; set; }
public string SearchQuery { get; set; }
public string OrderBy { get; set; } = "Id";
public string Fields { get; set; }
}
如果我没有在具体实现中的方法签名中添加 "where U : ShippingServicesResourceParameters" 并且在接口中添加 "where U : class" ,我会在第一次使用时出现 "Cannot convert from Method Group to String..." 错误resourceParams变量在具体实现中。 (在“.ApplySort(resourceParams.OrderBy”)
我在这里错过了什么?
让我们做你首先应该做的事情并制作一个演示问题的最小程序:
interface I
{
void M<U>(U u) where U : class;
}
class D
{
public void O() {}
}
class C : I
{
public void M<U>(U u) where U : D
{
u.O();
}
}
这是一个错误,因为 C 没有实现 I。它没有实现 I,因为:
I i = new C();
i.M<Giraffe>(new Giraffe());
现在我们有一只长颈鹿传递给 C.M<Giraffe>(Giraffe)
但 C.M<U>
要求 U 是 D。所以这是非法的。
我们不能这样修复它:
public void M<U>(U u) where U : class
{
u.O();
}
因为现在我们可以 D.O()
调用 Giraffe 类型的接收器。
因此我们必须这样修复它:
interface I
{
void M<U>(U u) where U : D;
}
class D
{
public void O() {}
}
class C : I
{
public void M<U>(U u) where U : D
{
u.O();
}
}
现在我们都很好。
您需要使实现约束与接口约束相匹配,就像您需要满足接口强加的所有其他要求一样。 接口是契约。你必须履行讨价还价的义务。
我注意到错误消息是这样说的:您必须匹配约束条件,但您没有这样做。注意错误信息;大多数时候他们会告诉你哪里出了问题。