views:

60

answers:

4

Say I have an enum something like:

enum OrderStatus
{
    AwaitingAuthorization,
    InProduction,
    AwaitingDespatch
}

I've also created an extension method on my enum to tidy up the displayed values in the UI, so I have something like:

public static string ToDisplayString(this OrderStatus status)
{
    switch (status)
    {
        case Status.AwaitingAuthorization:
            return "Awaiting Authorization";

        case Status.InProduction:
            return "Item in Production";

        ... etc
    }
}

Inspired by the excellent post here, I want to bind my enums to a SelectList with an extension method:

public static SelectList ToSelectList<TEnum>(this TEnum enumObj)

however, to use the DisplayString values in the UI drop down I'd need to add a constraint along the lines of

: where TEnum has extension ToDisplayString

Obviously none of this is going to work at all with the current approach, unless there's some clever trick I don't know about.

Does anyone have any ideas about how I might be able to implement something like this?

A: 

You could do this:

public static string ToOrderStatusDisplayString(this Enum status)
{    
    switch ((OrderStatus)status)
    {
         ...
    }
}

Then restrict TEnum to Enum: where TEnum : System.Enum

Of course, that way you get a bunch of methods on the Enum itself and lose type safety.

František Žiačik
[You cannot write `where TEnum : Enum`](http://stackoverflow.com/questions/1331739/enum-type-constraints-in-c/1416660#1416660).
SLaks
@SLaks: Oh yes, you're right. Give me -1, no mercy :)
František Žiačik
A: 

Instead of using "ToDisplayString", simply override ToString() of your enum. So if an enum overrides it it will take it, otherwise it will take the default ToString behavior (in ToSelectList).

Mike

Mike Gleason jr Couturier
+6  A: 

Is there a compelling reason to use an enum here?

When you start jumping through crazy hoops to use enums, it might be time to use a class.

public class OrderStatus
{
    OrderStatus(string display) { this.display = display; }

    string display;

    public override string ToString(){ return display; }

    public static readonly OrderStatus AwaitingAuthorization
        = new OrderStatus("Awaiting Authorization");
    public static readonly OrderStatus InProduction
        = new OrderStatus("Item in Production");
    public static readonly OrderStatus AwaitingDispatch
        = new OrderStatus("Awaiting Dispatch");
}

You consume it the same as an enum:

public void AuthorizeAndSendToProduction(Order order, ProductionQueue queue)
{
    if(order.Status != OrderStatus.AwaitingAuthorization) 
    {
        Console.WriteLine("This order is not awaiting authorization!");
        return;
    }
    order.Status = OrderStatus.InProduction;
    queue.Enqueue(order);
}

The string representation is built-in, and all you need is ToString().

Jay
I use this implementation a lot.
Robin Robinson
A: 

Could take a look at this question. I have used the attribute concept as well. The question has an example of a way you could implement this.

Robin Robinson