Frage

Ich nehme an, das mehr von einer öffentlichen rant ist, aber warum kann ich c # zu meiner Identifikation des Typs schließen nicht bekommen?

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

und eine definierte EntityObject mit einer Guid als Id wie folgt:

public Foo : EntityObject<Guid>

von der abstrakten Klasse EntityObject Vererben wie folgt definiert:

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

Die Verwendung der get-Methode würde wie folgt aussehen:

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

bearbeiten weitere Klarstellung.

War es hilfreich?

Lösung

Es ist schwer, gegeben zu sagen, dass Sie nur zwei Erklärungen gegeben haben, nicht, wie Sie sie verwenden. Ist idt ein anderer Typ Parameter irgendwo? (Wenn es TId waren, würde es vorschlagen - aber die Tatsache, dass Sie EntityT für einen anderen Typ Parameter, im Gegensatz zu Konventionen verwenden legt nahe, dass vielleicht IdT auch ist ...)

Jetzt IdT, vorausgesetzt, tatsächlich Guid in Ihrem Fall, wie soll der Compiler Arbeit darauf hin, dass Sie meinen Foo? Es könnten auch andere Arten von EntityObject<Guid> abzuleiten sein.

Kurz gesagt, Sie haben uns nicht gegeben genug Informationen alles, um sicher zu sagen, aber es klingt wie Sie im Grunde Zumutungen an den Compiler zu machen.

EDIT: Okay, hier ist meine Vermutung an, was Sie haben, normale Namenskonventionen verwendet:

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

Sie möchten tun:

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

Während zur Zeit Sie tun müssen:

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

Ja, der Compiler macht es sehr leicht härter für Sie als nötig. Eine ganze 6 zusätzliche Zeichen, aus Gründen der Sprache einfacher und die Regeln der Typinferenz halten leichter zu verstehen.

Im Grunde Typinferenz ist ein alles oder nichts Angelegenheit - entweder alle Typparameter abgeleitet werden oder keiner von ihnen ist. Das macht es einfach, wie Sie nicht brauchen, um herauszufinden, welche davon angegeben werden und welche nicht. Das ist ein Teil des Problems, und der andere Teil ist, dass Sie nur Einschränkungen für die Typparameter des Verfahrens zum Ausdruck bringen können - Sie können nicht haben:

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

, weil das TEntity ist beschränke, nicht TId. Auch hier macht diese Art der Sache Typinferenz einfacher.

Jetzt Sie könnte potenziell schreiben:

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

mit einem geeigneten Get Verfahren und eine zusätzliche Schnittstelle. Ich glaube, ich würde persönlich lieber nur wenn Get<Foo, Guid> verwenden.

Andere Tipps

Eine Erklärung wie

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

verlangt, dass idt ein konkreter ist. Wenn Sie idt auch parametrieren wollen, müssen Sie verwenden

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

Aber das ist wahrscheinlich nicht das, was man sich wünschen kann.

Das ist, warum ich alles habe, aber auf generische Schlüsseltypen mit generischen Einheiten aufgegeben. Ich konnte nicht herausfinden, wie meine Einheiten zu bekommen generische Schlüsseltypen zu haben, ohne dass die beide ganz über den Platz Beregnung. Jetzt habe ich auf Integer-Schlüssel gesetzt (das ist, was ich habe sowieso überall), aber es fühlt sich falsch an.

Wenn Ihre Methode Signatur sah wie folgt aus:

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

Der Compiler müßte etwas mit arbeiten ...

Sie rufen dann mit etwas erhalten wie:

EDIT (ich war falsch): Produkt p = Get (id);

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

Jons genagelt diese Antwort mit seinem Posten bis oben so werde ich den Mund halten und krieche zurück in meinem Loch.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top