Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#: Enums in Interfaces

I've seen a couple similar threads to this question, but none of them really answer the question I want to ask.

For starters, unfortunately I'm working with existing API code so sadly, while there may be a better way to do what I'm asking about, I'm locked in to doing it similarly to the way it is because backwards compatibility is non-negotiable.

I have a response class that currently contains an enum for an error code and a string description. The error codes define a fairly nice and complete set of responses that are all very semantically coupled to the operations where they're used.

Unfortuantely, I now have to add a different workflow for a similar set of API objects, and this will require a string description, which is fine, but also an enum error code consisting of a totally unrelated set of error codes. The error codes (and other aspects of the object model) will be used in lots of the same classes, so it would be nice to get a interface going so that i can run the objects through the same framework.

The intent here is to make a contract that says "I have an error code, and a description of that error code."

However, as far as I know there's no way to add an item to an interface such as

public interface IError
{
    enum ErrorCode;
    string Description;
}

nor is there a way to express

public interface IError<T> where T: enum
{
    T ErrorCode;
    string Description;
}

Anyone every run up against something like this before?

like image 889
bwerks Avatar asked Jun 30 '10 20:06

bwerks


1 Answers

Yes, I've run up against this. Not in this particular situation, but in other Stack Overflow questions, like this one. (I'm not voting to close this one as a duplicate, as it's slightly different.)

It is possible to express your generic interface - just not in C#. You can do it in IL with no problems. I'm hoping the limitation may be removed in C# 5. The C# compiler actually handles the constraint perfectly correctly, as far as I've seen.

If you really want to go for this as an option, you could use code similar to that in Unconstrained Melody, a library I've got which exposes various methods with this hard-to-produce constraint. It uses IL rewriting, effectively - it's crude, but it works for UM and would probably work for you too. You'd probably want to put the interface into a separate assembly though, which would be somewhat awkward.

Of course, you could make your interface just have T : struct instead... it wouldn't be ideal, but it would at least constrain the type somewhat. So long as you could make sure it wasn't being abused, that would work reasonably well.

like image 64
Jon Skeet Avatar answered Sep 28 '22 05:09

Jon Skeet