Matt
Matt

Reputation: 2790

Defining generic interface type constraint for value and reference types

Im having some trouble getting this generic constraint to work.

I have two interfaces below.

I want to be able to constrain the ICommandHandlers TResult type to only use types that implement ICommandResult, but ICommandResult has its own constraints that need to be supplied. ICommandResult could potentially return a value or reference type from its Result property. Am I missing something obvious? Thanks.

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

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

Upvotes: 6

Views: 691

Answers (4)

Botz3000
Botz3000

Reputation: 39600

You could change your interface to this (which looks kind of cleaner to me):

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

Or you could add the type parameter of ICommandResult<TResult> to your generic parameter list:

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

Upvotes: 1

qujck
qujck

Reputation: 14580

This should do it:

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

Upvotes: 0

DHN
DHN

Reputation: 4865

Hmm shouldn't your second interface look more like this?

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

Upvotes: 0

Oliver
Oliver

Reputation: 9002

You could add a 3rd generic type parameter to ICommandHandler:

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 );
}

Upvotes: 0

Related Questions