Question

Je suppose que cela est plus d'une diatribe publique, mais pourquoi ne puis-je obtenir c # pour déduire mon type de Id?

public EntityT Get<EntityT>(IdT id) where EntityT : EntityObject<IdT>

et un EntityObject défini avec un GUID en tant que Id comme suit:

public Foo : EntityObject<Guid>

Hériter de la classe abstraite EntityObject définie comme suit:

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

L'utilisation de la méthode get serait la suivante:

IRepository repository = new Repository();
var hydratedFoo = repository.Get<Foo>(someGuidId);

sous la direction de fournir des précisions supplémentaires.

Était-ce utile?

La solution

Il est difficile de dire étant donné que vous avez seulement donné deux déclarations, et non la façon dont vous les utilisez. Est-IdT un autre paramètre de type quelque part? (Si elle était TId, cela suggère qu'il est - mais le fait que vous utilisez EntityT pour un autre paramètre de type, contrairement aux conventions, suggère que IdT est peut-être aussi ...)

Maintenant, en supposant IdT est en fait Guid dans votre cas, comment le travail du compilateur que vous voulez dire devrait Foo? Il pourrait y avoir d'autres types découlant de EntityObject<Guid>.

En bref, vous ne nous avez pas donné suffisamment d'informations pour rien dire à coup sûr, mais il semble que vous êtes essentiellement des exigences déraisonnables sur le compilateur.

EDIT: D'accord, voici je pense à ce que vous avez, en utilisant les conventions de nommage normales:

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> {} 

Vous voulez faire:

IRepository repository = GetRepositoryFromSomewhere();
Foo foo = repository.Get<Foo>(someGuid);

Alors actuellement que vous devez faire:

Foo foo = repository.Get<Foo, Guid>(someGuid);

Oui, le compilateur rend très légèrement plus difficile pour vous que nécessaire. Tout un 6 caractères supplémentaires, par souci de garder la langue simple et les règles d'inférence de type plus facile à comprendre.

de type Fondamentalement, l'inférence est une affaire tout ou rien - soit tous paramètres de type sont ou inférée aucun d'entre eux est. Cela reste simple que vous n'avez pas besoin de travailler sur celles qui sont spécifiées et qui ne sont pas. Cela fait partie du problème, et l'autre partie est que vous ne pouvez exprimer des contraintes sur les paramètres de type de la méthode - vous ne pouvez pas avoir:

class Repository<TEntity>
{
    TEntity Get<TId>(TId id) where TEntity : EntityObject<TId>
}

parce que ce TEntity contraignant, pas TId. Encore une fois, ce genre de chose rend l'inférence de type simple.

Maintenant, vous peut potentiellement écrire:

Foo foo = repository.Get(someGuid).For<Foo>();

avec un procédé de Get approprié et une interface supplémentaire. Je pense que je préfère personnellement utiliser simplement Get<Foo, Guid> bien.

Autres conseils

Une déclaration comme

public EntityT Get<EntityT>(IdT id) where EntityT : EntityObject<IdT>

exige que IdT est un type concret. Si vous souhaitez paramétrer IdT ainsi, vous aurez besoin d'utiliser

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

Mais c'est probablement pas ce que vous voulez.

Voilà pourquoi je suis tout mais étant donné sur les principaux types génériques avec des entités génériques. Je ne pouvais pas comprendre comment obtenir mes entités d'avoir les principaux types génériques sans asperger les deux dans tous les sens. Maintenant, je l'ai installé sur les touches entières (ce qui est ce que j'ai partout de toute façon), mais il ne semble pas correct.

Si votre signature de la méthode ressemblait à ceci:

public TEntity Get<TEntity, TId>(TId id) where TEntity : EntityObject<TId>

Le compilateur aurait quelque chose à travailler avec ...

Vous appelez ensuite obtenir quelque chose comme:

EDIT (j'avais tort): produit p = Get (id);

Product p = Get<Product, Guid>(id);

Jon clouée cette réponse avec son poste en haut donc je me tais et ramper dans mon trou.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top