Lets say we have defined Planets
enum:
public enum Planets
{
Sun = 0,
Mercury=5,
Venus,
Earth,
Jupiter,
Uranus,
Neptune
}
I was using Enum.IsDefined
method for finding whether string exists in enum or not.
Enum.IsDefined(typeof(Planets), "Mercury"); // result is true
But, then I tried this and it returned true also:
Enum.IsDefined(typeof(Planets), 5); // result is true again
How, it comes? This method has not any overload. It has only one signature:
Enum.IsDefined(Type enumType, object value);
Why and how is Enum.IsDefined
searching for both name and value? And it is really interesting to me, why did they chosed that way? IMO making overloads would be better choice, not?
An enum type is a distinct value type (§8.3) that declares a set of named constants. declares an enum type named Color with members Red , Green , and Blue .
Enums in C# The enum keyword in C# declares a list of named integer constants. An enum can be defined in a namespace, structure or class. However, it is better to define it in a namespace so that all the classes can access it.
In C#, an enum (or enumeration type) is used to assign constant names to a group of numeric integer values. It makes constant values more readable, for example, WeekDays. Monday is more readable then number 0 when referring to the day in a week.
From Enum.IsDefined
method
The value parameter can be any of the following:
- Any member of type enumType.
- A variable whose value is an enumeration member of type enumType.
- The string representation of the name of an enumeration member. The characters in the string must have the same case as the enumeration member name.
- A value of the underlying type of enumType.
I believe that's the reason why it has no overload and takes object
as a second parameter. Since this method takes object
as a second parameter - and object
is a base class for all .NET types - you can pass string
or int
or etc..
Here how this method implemented;
public static bool IsDefined(Type enumType, Object value)
{
if (enumType == null)
throw new ArgumentNullException("enumType");
return enumType.IsEnumDefined(value);
}
And looks like this virtual Type.IsEnumDefined
method handles all of these cases in it's implementation like;
public virtual bool IsEnumDefined(object value)
{
if (value == null)
throw new ArgumentNullException("value");
if (!IsEnum)
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
Contract.EndContractBlock();
// Check if both of them are of the same type
Type valueType = value.GetType();
// If the value is an Enum then we need to extract the underlying value from it
if (valueType.IsEnum)
{
if (!valueType.IsEquivalentTo(this))
throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType", valueType.ToString(), this.ToString()));
valueType = valueType.GetEnumUnderlyingType();
}
// If a string is passed in
if (valueType == typeof(string))
{
string[] names = GetEnumNames();
if (Array.IndexOf(names, value) >= 0)
return true;
else
return false;
}
// If an enum or integer value is passed in
if (Type.IsIntegerType(valueType))
{
Type underlyingType = GetEnumUnderlyingType();
// We cannot compare the types directly because valueType is always a runtime type but underlyingType might not be.
if (underlyingType.GetTypeCodeImpl() != valueType.GetTypeCodeImpl())
throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), underlyingType.ToString()));
Array values = GetEnumRawConstantValues();
return (BinarySearch(values, value) >= 0);
}
}
In the documentation for Enum.IsDefined it states that this value is
Type: System.Object
The value or name of a constant in enumType.
You have given Mercury the value of 5
, therefore it is able to see this
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With