如何将泛型类型限制为 class 并支持 new()?

How do you constrain a generic type to be a class and support new()?

我正在尝试为 Cosmos DB Gremlin Graph API 数据源实现 GenericRepository 模式。所以我有:

  1. 添加并验证了与 w/my Cosmos 图形数据库接口的工作 Gremlin.Linq 库。
  2. 知道在 Generic Repository 中它实现了 TEntity,其中 TEntityclass。我也做过。
  3. 我现在正在实施我的通用存储库并想使用 Generic Extension with a clause for a new() 所以我收到了错误。我该怎么办?

错误 类型 'typename' 必须是具有 public 无参数构造函数的非抽象类型,以便将其用作泛型类型或方法 'generic'[=18= 中的参数 'parameter' ]

您可以在定义泛型类型时应用多个泛型约束,例如:

public class GenericRepository<TEntity> : IGenericRespository<TEntity> 
    where TEntity : class, new() //the new() constraint must come last

这些约束意味着要使类型与 GenericRespository<> 一起使用,它必须同时是 class(引用类型)它必须提供一个 public parameter-less 构造函数。 (参见 docs

实际上,这意味着您可以有一个 GenericRepository<object>,但不能有一个 GenericRepository<int>,因为 int 是一个 value-type,或者 GenericRepository<Uri>,因为尽管 Uri 是一个 class,它没有 public parameter-less 构造函数。

public class GenericRespository<T> 
    where T : class, new()
{
    public T Create() => new T();
}

public class Repositories
{
    //won't compile, int is a value type;
    readonly GenericRespository<int> intRepository = new GenericRespository<int>();

    //wont compile, Uri is a class, but no public
    //parameterless constructor
    readonly GenericRespository<Uri> uriRpository = new GenericRespository<Uri>(); //no public parameterless constructor, doesn't work.
    
    //object is a class and supports new object(), so this works
    readonly GenericRespository<object> objectRepository = new GenericRespository<object>(); //works fine
}

这些类型限制意味着您的 GenericRespository<TEntity> 将能够自行创建新的 TEntity 实例。这样做的真正价值在于,您将能够创建自己的 classes 并创建它们的存储库,而无需编写任何额外的代码。

正确答案是泛型可以有多个子句。所以我能够简单地通过扩展子句 (, new()) 来解决我的问题。现在 TEntity 必须是 classnew() 这对我有好处!