C# 泛型问题的推理

C# 泛型问题的推理,c#,generics,types,inference,C#,Generics,Types,Inference,我想这更像是公开的咆哮,但为什么我不能让c#推断我的Id类型呢 public EntityT Get<EntityT>(IdT id) where EntityT : EntityObject<IdT> public EntityT-Get(IdT-id)其中EntityT:EntityObject 以及定义的EntityObject,其Guid作为Id,如下所示: public Foo : EntityObject<Guid> public abstr

我想这更像是公开的咆哮,但为什么我不能让c#推断我的Id类型呢

public EntityT Get<EntityT>(IdT id) where EntityT : EntityObject<IdT>
public EntityT-Get(IdT-id)其中EntityT:EntityObject
以及定义的EntityObject,其Guid作为Id,如下所示:

public Foo : EntityObject<Guid>
public abstract class EntityObject<IdT>
{
    public IdT id { get; set; }
}
IRepository repository = new Repository();
var hydratedFoo = repository.Get<Foo>(someGuidId);
public Foo:EntityObject
从抽象EntityObject类继承,定义如下:

public Foo : EntityObject<Guid>
public abstract class EntityObject<IdT>
{
    public IdT id { get; set; }
}
IRepository repository = new Repository();
var hydratedFoo = repository.Get<Foo>(someGuidId);
公共抽象类EntityObject
{
公共IdT id{get;set;}
}
get方法的用法如下所示:

public Foo : EntityObject<Guid>
public abstract class EntityObject<IdT>
{
    public IdT id { get; set; }
}
IRepository repository = new Repository();
var hydratedFoo = repository.Get<Foo>(someGuidId);
IRepository repository=new repository();
var hydratedFoo=repository.Get(someGuidId);

编辑以提供进一步的澄清。

很难说,因为您只给出了两个声明,而没有说明如何使用它们。IdT是另一个类型参数吗?(如果它是
TId
,则表明它是-但是,与惯例相反,您正在为另一个类型参数使用
EntityT
,这一事实表明,
IdT
也可能是…)

现在,假设在您的例子中,
IdT
实际上是
Guid
,编译器应该如何计算出您的意思是
Foo
?可能还有从
EntityObject
派生的其他类型

简而言之,您没有给我们提供足够的信息来确定任何事情,但听起来您基本上对编译器提出了不合理的要求

编辑:好的,下面是我的猜测,使用正常的命名约定:

public interface IRepository
{
    TEntity Get<TEntity, TId>(TId id) where TEntity : EntityObject<TId>
}

public abstract class EntityObject<TId>
{
    public IdT id { get; set; }
}

public class Foo : EntityObject<Guid> {} 

使用适当的
Get
方法和额外的接口。我个人更喜欢使用
Get

如果你的方法签名是这样的:

public TEntity Get<TEntity, TId>(TId id) where TEntity : EntityObject<TId>
public tenty-Get(TId-id),其中tenty:EntityObject
编译器将有一些东西要处理

然后,您可以通过以下方式调用get:

编辑(我错了):产品p=Get(id)

productp=Get(id);
乔恩把他的帖子贴在了上面,所以我会闭嘴,爬回我的洞里。

像这样的声明

public EntityT Get<EntityT>(IdT id) where EntityT : EntityObject<IdT>
public EntityT-Get(IdT-id)其中EntityT:EntityObject
要求IdT是一种具体类型。如果您还想参数化IdT,则需要使用

public EntityT Get<EntityT, IdT>(IdT id) where EntityT : EntityObject<IdT>
public EntityT-Get(IdT-id)其中EntityT:EntityObject

但这可能不是您想要的。

这就是为什么我几乎放弃了使用泛型实体的泛型键类型。我不知道如何让我的实体具有通用键类型,而不将这两种类型洒得到处都是。现在我决定使用整数键(不管怎样,这是我在任何地方都有的),但感觉不对。

Jon,我为没有添加更多细节而道歉。同样,这是一个更即兴的咆哮,而不是一个真正合法的问题。但是imho编译器应该能够在编译时从foo对象确定IdT。很可能是我对泛型的假设导致了我对编译器如何能够/应该读取此文件的错误解释,但我假设直到编译时编译器才会链接模板化对象时才确定泛型类型。假设这样,确定引用对象的类型不是更进一步吗?泛型!=模板。你可能会得到一个C++编译器来“推断”这种事情,但是只要泛型是运行时,我就不会看到它发生,没有更明确的通用定义。IDT不是一个类型参数:<代码>获取< /代码> -只有一个类型参数,<代码> EntityT < /代码>。您还没有发布IRepository声明,或者什么对您不起作用。请给出一个完整的例子,说明您正在尝试做什么,并告诉我们发生了什么,而不是您想要什么。我更喜欢使用类似于公共类RepositoryBase{}公共类foodrepository:RepositoryBase{}@KeeperOfTheSoul:同意-但是您接下来将如何使用类型推断?我试图尽可能少地干扰原始设计。这当然有效,但让每个人痛苦地意识到Foo的键是Guid。@n8wrl我不理解你的评论。真的,Rob,我很感谢你的回答。但是,Repository.Get(someGuid)要求开发人员知道每个实体的Id类型。它也缺少库的语法甜度。(Guangid)会有。我不知道这是怎么一个问题…即使在C++中你也需要这个。不,ID(和实体)类型将被编译器推断出来。目前我们一直在使用guid,但是现在我们需要合并一个遗留数据库,我们现在正在处理复合id的想法。真糟糕。你想发现类型推断。调用泛型方法时不需要显式。@Rob:有时候不需要,有时候也需要。这取决于具体情况。