MAINAME KC
MAINAME KC

Reputation: 63

Two constraints with same base interface but both constraints cannot be the same

Is it possible to has a class with two constraints from same base class but they can't be the same class. Example as below:

public interface BaseMessage { }

public class RequestMessage: BaseMessage { }

public class ResponseMessage: BaseMessage { }

public class BaseDocumentDefinition<B,C> where B: BaseMessage where C: BaseMessage //<-- At here how to define B cannot same with C?
{
   Document<B> RequestDocument { get; set; }
   Document<C> ResponseDocument { get; set; }
   // ^Here need to prevent RequestDocument and ResponseDocument end up being same class
}

//This will get correct compilation
public class DerivedDocumentDefinition: BaseDocumentDefinition<RequestMessage, ResponseMessage> { }

//This will also get success compilation, because **RequestMessage** valid for both constraint
public class DerivedDocumentDefinition2: BaseDocumentDefinition<RequestMessage, RequestMessage> { }

Upvotes: 2

Views: 72

Answers (3)

Ehssan
Ehssan

Reputation: 759

What you want is not possible, but that is by design. With your constraint

class BaseDocumentDefinition<B, C> where B : IBaseMessage where C : IBaseMessage

you are basically saying that you need two types B and C, both of them providing all functionality specified in the interface IBaseMessage

So you want two types that can behave like a "base message". If that does not work for you, then you need to redefine your interfaces. If for example one of your "base messages" needs a method to provide a request and the other one a method to read a response, you'll have to split them into two interfaces, for example like this:

public interface IBaseMessage {   }

public interface IRequestMessage : IBaseMessage {
    dynamic GetRequestMessage(...);
}

public interface IResponseMessage : IBaseMessage {
    dynamic GetResponseMessage(...);
}

public interface IDocument<T> where T : IBaseMessage {   }

public class BaseDocumentDefinition<B, C> where B : IRequestMessage where C : IResponseMessage //<-- At here how to define B cannot same with C?
{
    IDocument<B> RequestDocument { get; set; }
    IDocument<C> ResponseDocument { get; set; }
}

Upvotes: 1

tsvedas
tsvedas

Reputation: 1069

As @grek40 said.

However, you can kind of force different types by throwing exception in the constructor. It is not intuitive but would solve your problem.

public BaseDocumentDefinition()
{
    if (typeof(B) == typeof(C))
    {
        throw new System.InvalidOperationException("Types must be different.");
    }
}

Upvotes: 1

grek40
grek40

Reputation: 13438

Basically, the where constraints only allow positive assumptions as in "X is Y", they do not allow negative assumptions as in "X is not Y".

So no, what you want is not possible. You will need some base class or interface that positively defines the expected difference.

Upvotes: 1

Related Questions