在给定当前代码的情况下,我应该如何将泛型应用于以下接口方法? [英] How should I apply generics to the following interface method, given current code?
问题描述
这是另一个问题的后续行动,我收到了很多很棒的评论和答案。
假设我有以下抽象类:
public abstract class Entity< TId> :IEquatable< Entity< TId>>
{
public TId Id {get;保护组; }
//加上IEquatable,GetHashCode覆盖等的实现。
}
我问的另一个问题是如何为实体命令实现接口,现在看起来像这样:
public接口ICommandEntities
{
void创建< TId>(实体< TId>实体);
无效更新< TId>(实体< TId>实体);
无效删除< TId>(实体< TId>实体);
void Reload< TId>(Entity< TId> entity);
}
之前,我试图弄清楚如何用泛型类型约束将方法参数限制为 Entity< TId>
类型。上一个问题的答案告诉我,我不需要这样做,我可以使用我的抽象类作为方法参数。
然而,我仍然没有了解如何在接口方法没有参数的情况下执行以下操作?
public interface IQueryEntities
{
IQueryable< TEntity>查询< TEntity>()where TEntity:???????;
}
当调用这个方法时,我只想传递一个像这样的泛型参数:
var queryable1 = queries.Query< EntityAbc>();
var queryable2 = queries.Query< EntityXyz>();
...实体类可能如下所示:
public class EntityAbc:Entity< string> {...}
public class EntityXyz:Entity< int> {...}
如何限制接口方法,以便它只允许从实体< TId>
作为一个通用参数传递? 改变你的接口是通用的:
public interface IQueryEntities< TId>
{
IQueryable< TEntity>查询< TEntity>()其中TEntity:实体< TId>
}
然后当您执行它时:
public class EntityAbc:Entity< string> ;, IQueryEntities< string>
或者可能是他的事件:
public abstract class Entity< TId> :IEquatable< Entity< TId>>,IQueryEntities< TId>
所以要更新以反映评论。通用接口仍然是一种方法。如果你不希望实现接口的实体没有问题,你可以这样做:
public class QueryEntities< TId> :IQueryEntities< TId>
{
public IQueryable< TEntity>查询< TEntity>()
其中TEntity:实体< TId>
{
...
}
}
使用它可能如下所示:
var queries = new QueryEntities< string>();
queries.Query< EntityAbc>();
但是,您无法发送任何实体进入该接口,除非您让该方法本身接收 TIn
。如果你想让这个方法本身是泛型的,那么代码就是这样:
var queries = new QueryEntities() ;
queries.Query< EntityAbc,string>();
界面如下所示:
public interface IQueryEntities
{
IQueryable< TEntity>查询< TEntity,TId>()其中TEntity:Entity< TId>
}
但你不想要。
This is a follow-up to another question where I received a lot of great comments and answers. That question brought up this one.
Say I have the following abstract class:
public abstract class Entity<TId> : IEquatable<Entity<TId>>
{
public TId Id { get; protected set; }
// plus implementation of IEquatable, GetHashCode override, etc.
}
The other question I asked had to do with how to implement an interface for entity commands, which now looks like this:
public interface ICommandEntities
{
void Create<TId>(Entity<TId> entity);
void Update<TId>(Entity<TId> entity);
void Delete<TId>(Entity<TId> entity);
void Reload<TId>(Entity<TId> entity);
}
Before, I was trying to figure out how to do this with generic type constraints to restrict the method arguments to be of type Entity<TId>
. Answers to the previous question told me I don't need to do that, I can just use my abstract class as the method argument.
However, I still don't understand how can I do the following, where the interface method has no arguments?
public interface IQueryEntities
{
IQueryable<TEntity> Query<TEntity>() where TEntity : ???????;
}
When Invoking this method, I only want to pass a single generic argument like so:
var queryable1 = queries.Query<EntityAbc>();
var queryable2 = queries.Query<EntityXyz>();
... where the entity classes might look something like this:
public class EntityAbc : Entity<string> {...}
public class EntityXyz : Entity<int> {...}
How can I constrain the interface method so that it only allows classes that extend from Entity<TId>
to be passed as a generic argument?
Change your interface to be generic:
public interface IQueryEntities<TId>
{
IQueryable<TEntity> Query<TEntity>() where TEntity : Entity<TId>;
}
and then when you implement it:
public class EntityAbc : Entity<string>, IQueryEntities<string>
or maybe event his:
public abstract class Entity<TId> : IEquatable<Entity<TId>>, IQueryEntities<TId>
So to update to reflect the comments. Making that interface generic is still the approach. If you didn't want the entities implementing the interface, no problem, you could do this:
public class QueryEntities<TId> : IQueryEntities<TId>
{
public IQueryable<TEntity> Query<TEntity>()
where TEntity : Entity<TId>
{
...
}
}
Using that might look like this:
var queries = new QueryEntities<string>();
queries.Query<EntityAbc>();
But, you're not going to be able to send any entity into that interface unless you make the method itself receive the TIn
. If you were to make the method itself generic like that the code would be this of course:
var queries = new QueryEntities();
queries.Query<EntityAbc, string>();
the interface for that looks like this:
public interface IQueryEntities
{
IQueryable<TEntity> Query<TEntity, TId>() where TEntity : Entity<TId>;
}
but you don't want that.
这篇关于在给定当前代码的情况下,我应该如何将泛型应用于以下接口方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!