Ras*_*par 6 c# generics types inference
我想这更像是一个公开咆哮,但为什么我不能用c#来推断我的Id类型?
public EntityT Get<EntityT>(IdT id) where EntityT : EntityObject<IdT>
Run Code Online (Sandbox Code Playgroud)
和Guid作为Id的已定义EntityObject如下:
public Foo : EntityObject<Guid>
Run Code Online (Sandbox Code Playgroud)
继承自如下定义的抽象EntityObject类:
public abstract class EntityObject<IdT>
{
public IdT id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
get方法的用法如下:
IRepository repository = new Repository();
var hydratedFoo = repository.Get<Foo>(someGuidId);
Run Code Online (Sandbox Code Playgroud)
编辑以提供进一步的说明.
鉴于您只给出了两个声明,而不是如何使用它们,所以很难说。IdT 是另一个类型参数吗?(如果是TId,那就表明它是 - 但事实上,您正在使用EntityT另一个类型参数,这与约定相反,表明也许IdT也是......)
现在,假设IdT实际上是Guid在你的情况下,编译器应该如何计算出你的意思Foo?可能还有其他类型派生自EntityObject<Guid>.
简而言之,您没有向我们提供足够的信息来确定任何事情,但听起来您基本上对编译器提出了不合理的要求。
编辑:好的,这是我使用正常命名约定对您所拥有的内容的猜测:
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> {}
Run Code Online (Sandbox Code Playgroud)
你想做:
IRepository repository = GetRepositoryFromSomewhere();
Foo foo = repository.Get<Foo>(someGuid);
Run Code Online (Sandbox Code Playgroud)
而目前你必须做:
Foo foo = repository.Get<Foo, Guid>(someGuid);
Run Code Online (Sandbox Code Playgroud)
是的,编译器使您的工作变得比必要的更加困难。总共 6 个额外字符,是为了让语言更简单,类型推断的规则更容易理解。
基本上,类型推断是一件全有或全无的事情——要么推断出所有类型参数,要么推断出其中一个。这使得事情变得简单,因为您不需要弄清楚哪些是被指定的,哪些是没有指定的。这是问题的一部分,另一部分是你只能表达对方法的类型参数的约束 - 你不能:
class Repository<TEntity>
{
TEntity Get<TId>(TId id) where TEntity : EntityObject<TId>
}
Run Code Online (Sandbox Code Playgroud)
因为那是限制TEntity,而不是TId。同样,这种事情使类型推断变得更简单。
现在你可以写:
Foo foo = repository.Get(someGuid).For<Foo>();
Run Code Online (Sandbox Code Playgroud)
使用适当的Get方法和额外的接口。我想我个人更喜欢直接使用Get<Foo, Guid>。
| 归档时间: |
|
| 查看次数: |
474 次 |
| 最近记录: |