在.net泛型中使用子类型约束的真实示例

本文关键字:约束 真实 类型 泛型 net | 更新日期: 2023-09-27 18:09:31

是否有在。net泛型中对类型参数使用子类型约束的实际示例?我所说的"子类型约束"是指

where T : <base class name>

where T : U

可能有一些标准泛型与相应的约束?或专门的通用。net库。

UPD有很多接口约束的好例子

where T : <interface name>

但是子类型约束似乎非常具体,不太有用。我试着去理解,在哪些情况下这种约束是至关重要的。Luaan的回答包含了来自ASP的where T : <base class name>的例子。. NET MVC,但我仍然对where T : U约束的实际示例感兴趣。

在.net泛型中使用子类型约束的真实示例

我将它们用于数据访问层中的存储库类,例如

public interface IRepository<T>
    where T : IDbItentity
{
    IList<T> GetAll();
    T GetById(int id);
    int Insert(T saveThis);
    void Update(T updateThis);
    void Delete(T deleteThis);
}

其中IDBItentity是一个接口,如下所示:

public interface IDbItentity
{
    int Id { get; }
}

这是你经常使用的东西。在某种程度上,它模仿了正常继承的工作方式。

因此,例如,如果你有一个围绕O/RM实体构建的通用功能,你可以创建一个实体基类,并将其用作操纵该实体的所有不同数据层的类型约束。

与接口一起使用非常有用。

通常,你会写一些关于其他东西的包装。

的基本思想是,当您真的只想让类型参数适合某些用例时,您可以使用这些参数,而不是仅仅使用接口,而是让代码的用户提供他们的具体类型。它仍然实现了所有你需要正确工作的东西,但与此同时,用户可以使用所有的功能,甚至是那些你不知道的。

在BCL中你不会发现很多病例。基本上,这与类型约束是约束这一事实有关。BCL通常使用泛型类型和方法来编写非常通用的功能——我猜这部分是因为大多数BCL都是在泛型之前出现的,而且因为大多数时候,继承即使不是更好,也会一样好。

不过还是有区别的。假设您需要一些实体的集合。如果你只使用List<Entity>,你是在说"我期待任何实体,谢谢"。如果你使用List<T> where T : Entity(伪代码),你在说"我需要知道你给我的类型是一个实体,但我只想要整个集合中的一种实体"。

总而言之,如果你想要好的泛型类型约束的应用程序,看看新的代码。例如,在ASP。NET MVC,有这样的东西:

public abstract class CachedAssociatedMetadataProvider<TModelMetadata> 
       : AssociatedMetadataProvider 
       where TModelMetadata : ModelMetadata
public class DataAnnotationsModelValidator<TAttribute>
       : DataAnnotationsModelValidator 
       where TAttribute : ValidationAttribute

当您使用Action s(或事件)从外部将功能标记到某些此类一般类时,它也非常有用。

同样,它们的用法基本如下:

  • 限制可以在类中使用的类型
  • 确保传递给您的类型符合某些合同
  • 提高代码用户的可用性
  • 值类型的性能优化,主要避免装箱-例如,您可以使用IComparable而不必装箱

通常用于扩展方法,例如:

   public static string Parse<Tenum>(this object spr, int id) where Tenum : struct, IConvertible 
   {
       Contract.Ensures(typeof(Tenum).IsEnum, "type must be is enum");
       return ((Tenum)(object)id).ToString();
   }
 string ProductTypeTitle =  this.Parse<ProductType>(product.ProductTypeID);