Проблема действительно в том, что есть два Receive
метода, которые отличаются только типом возвращаемого значения. Поскольку ваш тип представляет дуплексный канал, вам пришлось дублировать все в интерфейсе - я полагаю, что более простой подход - определить тип, который позволяет вам представлять "либо T, либо U" . Это очень похоже на Tuple<T, U>
, который сейчас находится в .NET, что позволяет вам представлять "и T, и U" . Сигнатура типа может выглядеть так:
// Represents either a value of type T or a value of type U
class Either<T, U> {
public bool TryGetFirst(out T val);
public bool TryGetSecond(out U val);
}
// For constructing values of type Either<T, U>
static class Either {
public static Either<T, U> First<T, U>(T val);
public static Either<T, U> Second<T, U>(U val);
}
Пример использования этого класса может выглядеть следующим образом:
var val = Either.First<int, string>(42);
int num;
string str;
if (val.TryGetFirst(out num))
Console.WriteLine("Got number: {0}", num);
else if (val.TryGetSecond(out str))
Console.WriteLine("Got string: {0}", str);
Тогда вы можете представить свой дуплексный канал, используя более простой интерфейс:
public interface IDuplexChannel<T, U> {
void Send(Either<T, U> value, int timeout = -1);
bool TrySend(Either<T, U> value, int timeout = -1);
Either<T, U> Receive(int timeout = -1);
bool TryReceive(out Either<T, U> value, int timeout = -1);
}
Как предполагает Джош, я бы также избавился от методов Receive
и Send
. Зачем? Потому что это делает реализацию интерфейса простой, и вы можете легко обеспечить реализацию Receive
и Send
в терминах TryReceive
и TrySend
в качестве метода расширения. Итак, вы получите интерфейс:
public interface IDuplexChannel<T, U> {
bool TrySend(Either<T, U> value, int timeout = -1);
bool TryReceive(out Either<T, U> value, int timeout = -1);
}
И методы расширения будут выглядеть примерно так:
public static Either<T, U> Receive
(this IDuplexChannel<T, U> ch, int timeout = -1) {
Either<T, U> v;
if (!ch.TryReceive(out v, timeout)) throw new Exception(...);
return v;
}