Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 );
}
like image 684
Matt Avatar asked Mar 18 '13 10:03

Matt


People also ask

What does the generic constraint of type interface do?

Interface Type Constraint You can constrain the generic type by interface, thereby allowing only classes that implement that interface or classes that inherit from classes that implement the interface as the type parameter.

How do you specify a constraint for the type to be used in a generic class?

It will give a compile-time error if you try to instantiate a generic type using a type that is not allowed by the specified constraints. You can specify one or more constraints on the generic type using the where clause after the generic type name.

How do you declare a generic interface?

You can declare variant generic interfaces by using the in and out keywords for generic type parameters. ref , in , and out parameters in C# cannot be variant. Value types also do not support variance. You can declare a generic type parameter covariant by using the out keyword.

How do you define generic type?

Definition: “A generic type is a generic class or interface that is parameterized over types.” Essentially, generic types allow you to write a general, generic class (or method) that works with different types, allowing for code re-use.


1 Answers

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 );
}
like image 113
Botz3000 Avatar answered Sep 30 '22 15:09

Botz3000