各地缺乏与约束部分泛型类型推断的工作 [英] Working around lack of partial generic type inference with constraints

查看:111
本文介绍了各地缺乏与约束部分泛型类型推断的工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有了这个成员的接口(这是用于存储库):

I have an interface (which is used by repositories) that has this member:

T FindById<T, TId>(TId id)
    where T : class, IEntity<TId>
    where TId : IEquatable<TId>;

这允许调用者指定一个实体类型( T )和它的类型是编号字段( TID )。那么这个接口的实现会发现类型的实体 T ,并使用 ID 参数,根据过滤它们自己ID(这是上定义的 IEntity< TID>

This allows the caller to specify an entity type (T) and the type of it's Id field (TId). The implementor of this interface would then find the entities of type T and use the id parameter to filter them according to their id (which is defined on IEntity<TId>).

目前,我称它是这样的:

Currently I'm calling it like this:

int id = 123;
var myApproval = PartsDC.FindById<Approval, int>(id);



在理想情况下,我想做到这一点:

Ideally I'd like to do this:

int id = 123;
var myApproval = PartsDC.FindById<Approval>(id);



我读过这个问题的答案:

I've read the answers for this question:

部分泛型类型推断在C#中可能吗?

我明白我不能得到我想要的语法,但可以亲近。我不能完全得到它设置权在我的情况,但因为我的泛型参数约束

I understand I can't get the syntax I want, but can get close. I can't quite get it setup right in my case though because of my generic parameter constraints.

下面是我到目前为止有:

Here's what I have so far:

public class FindIdWrapper<T> where T : class
{
    public readonly IDataContext InvokeOn;

    public FindIdWrapper(IDataContext invokeOn)
    {
        InvokeOn = invokeOn;
    }

    T ById<TId>(TId id) where TId : IEquatable<TId>
    {
        return InvokeOn.FindById<T, TId>(id);
    }
}

public static class DataContextExtensions
{
    public static FindIdWrapper<T> Find<T>(this IDataContext dataContext) where T : class, IEntity
    {
        return new FindIdWrapper<T>(dataContext);
    }
}



编译错误我得到的是:

The compilation error I get is:

类型'T'不能在泛型类型或方法可以用作类型参数'T''PartsLegislation.Repository.IDataContext.FindById< T,TID> (TID)。有一个从'T'没有隐式引用转换PartsLegislation.Repository.IEntity< TID>'。

我明白它的说法,因为在 T 在我的包装类只约束为引用类型,但 FindById 函数希望它是 IEntity< TID> ,但我不能这样做,因为 TID 是方法(否则我回来了在广场的一个)。

I understand what it's saying because the T in my wrapper class is only constrained to be a reference type, but the FindById function wants it to be IEntity<TId>, but I can't do that as the TId is in the method (otherwise I'm back at square one).

我怎样才能解决这个问题(或不能我)?

How can I get around this issue (or can't I)?

推荐答案

这不能工作通常的方式周围,因为你不能在事后说服 TID 约束的编译器。你可以,但是,相反的顺序,即

That can't work the usual way around because you can't convince the compiler of the TId constraint after the fact. You can, however, reverse the sequence, i.e.

var obj = ById(id).Find<SomeType>();



不优雅,但它的作品。执行:

Not as elegant, but it works. Implementation:

public Finder<TId> ById<TId>(TId id) where TId : IEquatable<TId>
{
    return new Finder<TId>(this, id);
}
public struct Finder<TId> where TId : IEquatable<TId>
{
    private readonly YourParent parent;
    private readonly TId id;
    internal Finder(YourParent parent, TId id)
    {
        this.id = id;
        this.parent = parent;
    }
    public T Find<T>() where T : class, IEntity<TId>
    {
        return parent.FindById<T, TId>(id);
    }
}



警告:它可能是更容易只是告诉它既参数类型明确。

caveat: it is probably easier just to tell it both the parameter types explicitly.

这篇关于各地缺乏与约束部分泛型类型推断的工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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