开发者

How can a variable typed as an enum take a value that is out of range of its elements?

Can anyone explain to me how an a member of this开发者_运维问答 enum takes a value of 0?

public enum EnumLogicalOperator
{
    And = 1,
    Or = 2
}

How can a variable typed as an enum take a value that is out of range of its elements?


How can a variable typed as an enum take a value that is out of range of its elements?


How can a variable typed as an enum take a value that is out of range of its elements?


Whenever you use default(EnumLogicalOperator) or new EnumLogicalOperator() you'll get a zero value. In other words, the default value of an enum type member is always 0. All enums will have the value 0 until you set them to something else.


An instance of an enum type can be created from any legal value of its underlying type, even if no 'named' member of the enumeration is associated with that underlying value. In particular, it's common to see the value 0 because:

  1. It is the default value of enumeration types.
  2. For convenience, C# lets you implicitly convert the literal 0 to any enumeration type.


The default value of an enum is 0; I believe the standard recommendation is that you always include something assigned to 0 inside your enum to account for this ("Unknown" or "None" both work well in my experience).


It's mentioned on this page: http://msdn.microsoft.com/en-us/library/sbbt4032%28v=vs.80%29.aspx

The default value of an enum E is the value produced by the expression (E)0

So basically, the default value will always be the integer value 0. So I would guess that what you've got here is that LogicalOperatorWithPreviousRule has never been assigned a value.


From the C# Language Specification (section 1.10, Enums):

The set of values that an enum type can take on is not limited by its enum members. In particular, any value of the underlying type of an enum can be cast to the enum type and is a distinct valid value of that enum type.

Also, section 4.1.2, Default constructors specifies that enums default to 0.

Download the document, it contains lots of interesting information :-)


An enum can have any value based on its underlying type (Int32 in your case).

EnumLogicalOperator op = (EnumLogicalOperator) 0;
EnumLogicalOperator op = (EnumLogicalOperator) 100;
EnumLogicalOperator op = (EnumLogicalOperator) 900000;
EnumLogicalOperator op = (EnumLogicalOperator) -1;

private EnumLogicalOperator _op; // As a class member, will default to 0

Be sure to use Enum.IsDefined when validating your input and handle error conditions. Also generally a good idea to include 0 as the value for one of your enum values.


The default value of an integer variable is 0. And because the default underlying type of every enumeration element is int, which represents an integer, the default value of your variable will be 0.

The documentation makes this explicit:

The default value of an enum E is the value produced by the expression (E)0.


The only way to get a different default value is to explicitly initialize it when you declare the variable:

EnumLogicalOperator x = EnumLogicalOperator.Or;

This is why it's generally recommended that 0 correspond to a valid element in your enumeration, because this will be the default value of all variables of that type.


In addition, it is possible to assign any arbitrary integer value to a variable typed as an enum. The documentation warns:

It is possible to assign any arbitrary integer value to meetingDay. For example, this line of code does not produce an error: meetingDay = (Days) 42. However, you should not do this because the implicit expectation is that an enum variable will only hold one of the values defined by the enum. To assign an arbitrary value to a variable of an enumeration type is to introduce a high risk for errors.

And this is made even clearer by the C# Language Specification (specifically, section 1.10 on enums):

The set of values that an enum type can take on is not limited by its enum members. In particular, any value of the underlying type of an enum can be cast to the enum type and is a distinct valid value of that enum type.

This is why it's very important that public framework methods always verify that the value specified is within the range of valid values for that enumeration. You can't rely on the type checking system to ensure this for you. The Framework Design Guidelines recommend:

Do argument validation. Do not assume enum arguments will be in the defined range. It is legal to cast any integer value into an enum even if the value is not defined in the enum.


I would suggest you include a member "Undefined" with value 0 or make your "And" or "Or" the 0-value.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜