You cannot add or remove method from generic interface based on the type. Also, CLR doesn’t support higher kinded types (as of now). Let’s say that we want to encode state of an object in its type and disallow some operations depending on the state.

In our example we will use issue. We can assign issue if it is unassigned. We cannot assign it for the second time. We can move issue from backlog to sprint (so it is a todo item) but we cannot do it for the second time. Of course, those requirements are just for an example.

Let’s go with the following code:

The trick here is to use phantom types, types which we cannot create. In this example those are Assigned and Todo. So we can do this:

But we cannot do this:

If we didn’t use generics, we would need to use a lot of inheritance: AssignableTodoableIssue, TodoableAssignedIssue, AssignableTodoIssue, AssignedTodoIssue. Imagine now adding more state.

You can find similar solution in Scala in Action, look for phantom types.