views:

210

answers:

5

Consider the following method,

public void Add(Enum key, object value);

Since Enum is a "special class", I didn't realize you could use the type in this way, but it compiles. Now, the .NET Framework Design Guidelines don't have anything to say about this construction, so I'm curious what everyone else thinks about this.

Here is what this method is doing internally:

public void Add(Enum key, object value)
{
   this.dict.Add(key.ToString(), value)
}

Did you expect the parameter to be converted to a string or cast to an int?

Consider the following use-case,

public enum Names
{
   John,
   Joe,
   Jill,
}

Add(Names.John, 10);
Add(Names.Joe, 11);

Is using enum in this way an acceptable alternative to using string constants (given that the domain is the set of all strings which are also valid enum identifiers)?

Last question: Does anyone know of any other real world scenarios that required passing the abstract Enum base class as parameter?

+4  A: 

Yes, using Enum as a parameter type is completely valid.

Taylor Leese
I'm surprised this comment received so many points because it has no detail.
Dave
It was the first answer that directly answered your question.
Yuriy Faktorovich
+2  A: 

A recent example of using the Enum class was to extend it to get the DescriptionAttribute of a specified Enum value: link.

Yuriy Faktorovich
That's a very clever use. Hopefully that works with the InternalsVisibleTo attribute in a way the integrates with Intellisense.
Dave
+4  A: 

It's absolutely valid to use an enum value as a parameter.

Is using enum in this way an acceptable alternative to using string constants(...)?

Yes, in fact this is one of the main uses of enums.

Using a general Enum value is a little less obvious, since you generally want to know what values you can expect. A common use of enum values is to use it in a switch statement, and it helps to know what values can be expected. The name of an enum value is not generally that important, it's what it represents.

Rik
If you "Go to definition" in Visual Studio on the Enum type, you'll be presented with the definition of the "public abstract class Enum" which contains the static methods and instance methods like ToObject.
Dave
+1  A: 

Yes it is completely valid. But make sure that the enum's visibility is equal to the method's visibility.

In other words: If your method is public, make the enum public. Otherwise you'd be unable to invoke the method.

The String's Equals method uses an enum as the optional second parameter for comparison options:

String s = "Hello";
s.Equals("hello", StringComparison.OrdinalIgnoreCase);

EDIT: After rereading your question I understand what you are asking. I personally don't see the benefit of passing an Enum element to only convert it to a string.

I guess you are trying to accommodate several different derived enum types? Would it be better to either store the enum into the dictionary, or limit the parameter to a specific derived instance?

You aren't solving the problem of key uniqueness if you are allowing any derived enum to be passed into the method.

Chris
I suppose this limitation arises at run-time as an exception? The second part of your answer is not relevant to my question -- of course you can pass types derived from System.Enum to methods (in this case StringComparison) and it is a good idea to do so.
Dave
I think your last point is a valid one -- it's a shame that Enum doesn't work as a constraint on a generic method.
Dave
It would be able to work as a constraint if you created a derived enum that contained all valid strings. But I think it would be better to use the dictionary in your example to enforce string uniqueness.
Chris
A: 

If you design a factory pattern to generate classes for different Products with different uses and of course a common base. But all of this products has Enums that describes their actions or States.

You could have a method to generate those products in the base class like

public class ProductsFactory
{
public static BaseProduct Create( string ProductName, Enum State)
{
....
  return new ProductX;
}
}
public class SailBoat: BaseProduct
{
public enum BoatState
{
Sailing,
Docked,
}
}

public class Airplain: BaseProduct
{
public enum AirplainState
{
Flying,
Landing,
TakingOff
}
}

void main
{
ProductFactory.Create("SailBoat", SailBoat.BoatState.Sailing);
ProductFactory.Create("Airplain", Airplain.AirplainState.Flying);
}
jmayor