在给定当前代码的情况下,我应该如何将泛型应用于以下接口方法? [英] How should I apply generics to the following interface method, given current code?

查看:105
本文介绍了在给定当前代码的情况下,我应该如何将泛型应用于以下接口方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是另一个问题的后续行动,我收到了很多很棒的评论和答案。

假设我有以下抽象类:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆