2013-03-18 5 views
6

У меня есть некоторые проблемы с тем, чтобы получить это общее ограничение для работы.Определение ограничения типа общего интерфейса для значений и ссылочных типов

У меня есть два интерфейса ниже.

Я хочу, чтобы иметь возможность ограничивать тип ICommandHandlers TResult только для типов, реализующих ICommandResult, но у ICommandResult есть свои ограничения, которые необходимо предоставить. ICommandResult может потенциально вернуть значение или ссылочный тип из свойства Result. Мне что-то не хватает? Благодарю.

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

Я не вижу, что это связано с ссылочными типами и типами значений. –

+0

Свойство ICommandResult Result может быть либо значением, либо ссылочным типом. – Matt

+0

Так может ли любой другой общий тип, если только он не ограничен «где T: class/struct», ? –

ответ

1

Вы можете изменить интерфейс для этого (который выглядит вроде чище меня):

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

Или вы могли бы добавить параметр типа от ICommandResult<TResult> в список общих возможностей:

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

Спасибо, я думаю, что ваш первый вариант является самым элегантным. – Matt

0

Вы можете добавить 3-й параметр универсального типа для 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); 
} 
0

Хм Не следует ли ваш второй интерфейс выглядеть следующим образом?

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

'out' там? Я считаю, что это невозможно! –

+0

Ну, это часть, о которой я не был уверен. Я сейчас работаю с .Net 3.5 ... Я удалю его. – DHN

+0

Вы можете определить, что параметр является контравариантным в определении интерфейса: D –

0

Это следует сделать это:

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