如何将泛型类型限制为 class 并支持 new()?
How do you constrain a generic type to be a class and support new()?
我正在尝试为 Cosmos DB Gremlin Graph API 数据源实现 GenericRepository 模式。所以我有:
- 添加并验证了与 w/my Cosmos 图形数据库接口的工作 Gremlin.Linq 库。
- 知道在 Generic Repository 中它实现了
TEntity
,其中 TEntity
是 class
。我也做过。
- 我现在正在实施我的通用存储库并想使用 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
必须是 class
和 new()
这对我有好处!
我正在尝试为 Cosmos DB Gremlin Graph API 数据源实现 GenericRepository 模式。所以我有:
- 添加并验证了与 w/my Cosmos 图形数据库接口的工作 Gremlin.Linq 库。
- 知道在 Generic Repository 中它实现了
TEntity
,其中TEntity
是class
。我也做过。 - 我现在正在实施我的通用存储库并想使用 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
必须是 class
和 new()
这对我有好处!