簡體   English   中英

為什么以及如何(內部)Enum.IsDefined搜索名稱和值?

[英]Why and how (internally) does Enum.IsDefined search for both name and value?

讓我們說我們定義了Planets枚舉:

public enum Planets
{
    Sun = 0,
    Mercury=5,          
    Venus,              
    Earth,          
    Jupiter,        
    Uranus,         
    Neptune   
}

我正在使用Enum.IsDefined方法來查找字符串是否存在於枚舉中。

Enum.IsDefined(typeof(Planets), "Mercury"); // result is true

但是,然后我嘗試了這個,它也返回true:

Enum.IsDefined(typeof(Planets), 5); // result is true again

它是怎么來的? 這種方法沒有任何過載。 它只有一個簽名:

Enum.IsDefined(Type enumType, object value);

為什么以及如何使用Enum.IsDefined搜索名稱和值? 這對我來說真的很有趣,為什么他們這樣選擇? IMO制造超載會是更好的選擇,不是嗎?

來自Enum.IsDefined方法

value參數可以是以下任何一項

  • 任何類型為enumType的成員。
  • 一個變量,其值是enumType類型的枚舉成員。
  • 枚舉成員名稱的字符串表示形式。 字符串中的字符必須與枚舉成員名稱具有相同的大小寫。
  • enumType的基礎類型的值。

我相信這就是它沒有過載並將object作為第二個參數的原因。 由於此方法將object作為第二個參數 - object是所有.NET類型的基類 - 您可以傳遞stringint等。

這里實現了這種方法;

public static bool IsDefined(Type enumType, Object value)
{
     if (enumType == null)
         throw new ArgumentNullException("enumType");                    
     return enumType.IsEnumDefined(value);
}

看起來像這個虛擬的Type.IsEnumDefined方法在它的實現中處理所有這些情況;

    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);
        }
    }

Enum.IsDefined的文檔中,它聲明了這個值

鍵入:System.Object

enumType中常量的值或名稱。

你給了Mercury 5的值,因此能夠看到它

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM