2013-03-18 8 views
6

Ich habe Probleme, diese generische Integritätsbedingung zu erhalten.Generische Schnittstellentypbeschränkung für Wert- und Referenztypen definieren

Ich habe zwei Schnittstellen unten.

Ich möchte in der Lage sein, den ICommandHandlers TResult-Typ zu beschränken, um nur Typen zu verwenden, die ICommandResult implementieren, aber ICommandResult hat seine eigenen Einschränkungen, die angegeben werden müssen. ICommandResult konnte möglicherweise einen Wert oder Referenztyp aus seiner Result-Eigenschaft zurückgeben. Fehle ich etwas Offensichtliches? Vielen Dank.

public interface ICommandResult<out TResult> 
{ 
    TResult Result { get; } 
} 

public interface ICommandHandler<in TCommand, TResult> where TCommand : ICommand 
                 where TResult : ICommandResult<????> 
{ 
    TResult Execute(TCommand command); 
} 
+0

Ich sehe nicht, was das mit Bezugstypen und Werttypen zu tun hat –

+0

Die ICommandResult Result -Eigenschaft kann entweder ein Wert oder Referenztyp sein. – Matt

+0

So kann jeder andere generische Typ, außer mit "where T: class/struct" ? –

Antwort

1

Sie könnten Ihre Schnittstelle zu diesem ändern (der Art von sauber mir aussehen):

public interface ICommandHandler<in TCommand, TResult> where TCommand : ICommand 
{ 
    ICommandResult<TResult> Execute(TCommand command); 
} 

Oder Sie könnten die Typ-Parameter hinzufügen von ICommandResult<TResult> zu Ihrer allgemeinen Parameterliste:

public interface ICommandHandler<in TCommand, TCommandResult, TResult> 
    where TCommand : ICommand 
    where TCommandResult: ICommandResult<TResult> 
{ 
    TCommandResult Execute(TCommand command); 
} 
+0

Danke, ich denke, Ihre erste Option ist die eleganteste. – Matt

0

Sie könnten einen dritten generischen Typparameter zu ICommandHandler hinzufügen:

public interface ICommandResult<out TResult> 
{ 
    TResult Result { get; } 
} 

public interface ICommandHandler<in TCommand, TResult, TResultType> 
                 where TCommand : ICommand 
                 where TResult : ICommandResult<TResultType> 
{ 
    TResult Execute(TCommand command); 
} 
0

Hmm sollte nicht Ihre zweite Schnittstelle aussehen wie diese?

public interface ICommandHandler<in TCommand, ICommandResult<TResult>> 
    where TCommand : ICommand 
{ 
    TResult Execute(TCommand command); 
} 
+0

'out' da? Ich glaube, das ist nicht möglich! –

+0

Nun, das ist der Teil, über den ich mir nicht sicher war. Ich arbeite gerade mit .Net 3.5 ... Ich werde es entfernen. – DHN

+0

Sie können definieren, dass ein Parameter in der Schnittstellendefinition kontravariant ist: D –

0

Dies sollte es tun:

public interface ICommandHandler<in TCommand, out TResult> 
    where TCommand : ICommand 
    where TResult : ICommandResult<TResult> 
{ 
    TResult Execute(TCommand command); 
}