使用 IEnumerable<> 作为可以获取引用和非引用类型的泛型方法的参数



我试图建立一个验证属性,将验证集合的大小,我希望该方法能够处理引用类型,如字符串和非引用类型,如int。我试图使用IEnumerable<object>,但在我通过IEnumerable<int>的情况下保持为空。

这是我当前的代码-

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
public class EnumerableSizeAttribute : ValidationAttribute<IEnumerable<object>>
{

protected override ValidationResult? IsValid(IEnumerable<object>? enumerable, ValidationContext validationContext)
{
//check collection size
}
}

我应该使用什么作为参数来允许我将任何集合类型传递到方法中?谢谢你的帮助!

值和引用类型之间的一般方差规则是…复杂。

如果需要避免装箱,则考虑使方法本身具有泛型并采用IEnumerable<T>,以便调用者指定它(通常是隐式的,因此无需更改代码)。

如果这不是一个选项:考虑使用非通用的IEnumerableapi。或者IListICollection,因为你在计数之后,你可以通过.Count便宜地访问它们,而无需支付与IEnumerable相关的任何装箱/迭代开销。

. NET 7及以后的版本可以使用泛型属性:

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
public class EnumerableSizeAttribute<T> : ValidationAttribute<IEnumerable<T>>
{

protected override ValidationResult? IsValid(IEnumerable<T>? enumerable, ValidationContext validationContext)
{
//check collection size
}
}

IsValid内部,您可以检查enumerable是否为ICollection<T>,从而使用便宜的Count属性来检查大小:

if(enumerable is ICollection<T> col && col.Count <...)
{

}

您也可以使用属性模式匹配,尽管我对语法仍然不太熟悉。就像

if(enumerable is ICollection<T> {Count: < MaxLength} col)
{

}

最新更新