簡體   English   中英

為什么我不能將整數轉換為枚舉

[英]Why can't I cast an integer to an enumeration

我正在嘗試從已經確認等於0的DataGridViewRow單元格值強制轉換為整數

AddedTask.Status = (TaskStatus) row.Cells["status"].Value;

Visual Studio中的InvalidCastException

這是創建Task對象和TaskStatus枚舉的代碼。

class Task
{
    public string Description { get; set; }

    public TimeSpan Duration
    {
        get
        {
            if (BeginDate == DateTime.MinValue) // BeginDate has not been set
                return new TimeSpan(0, 0, 0);
            else if (EndDate == DateTime.MinValue)
                return DateTime.Now.Subtract(this.BeginDate);
            else
                return this.EndDate.Subtract(this.BeginDate);
        }
    }

    public DateTime BeginDate { get; set; }
    public DateTime EndDate { get; set; }
    public TaskStatus Status { get; set; }

    public Task()
    {
        this.Description = string.Empty;
        this.BeginDate = new DateTime();
        this.EndDate = new DateTime();
        this.Status = TaskStatus.UNINVOICED;
    }
}

public enum TaskStatus
{
    UNINVOICED,
    INVOICED,
    PAID
}

我進行了一些測試,發現如果原始值是Int32 ,則轉換成功,但如果原始值是Int64byte ,則轉換失敗。

我建議的解決方案是在Convert.ToInt32()之前使用Convert.ToInt32()

AddedTask.Status = (TaskStatus) Convert.ToInt32(row.Cells["status"].Value);

來自docs.microsoft.com

枚舉是一組命名常量,其基礎類型是任何整數類型。 如果未顯式聲明任何基礎類型,則使用Int32。

因此,您的TaskStatus枚舉是從Int32派生的,任何其他整數類型的直接強制轉換都會失敗。

這可行,但是如果這是我可能要退休的C#的唯一方法。

AddedTask.Status = (TaskStatus) Enum.Parse(typeof(TaskStatus), row.Cells["status"].Value.ToString());

作為旁注。 使用枚舉時,在通過服務持久化或公開時,應使用該枚舉的字符串。

var value = TaskStatus.UNINVOICED;
var x = value.ToString();

var reversed = (TaskStatus)Enum.Parse(typeof(TaskStatus), x);

您想要保留的原因是可以在將來修改枚舉。 如果在第1天您的枚舉看起來像這樣:

public enum TaskStatus
{
    UNINVOICED,
    INVOICED,
    PAID
}

UNINVOICED的int值可以為0,INVOICED的值可以為1,PAID的值可以為2。

然后,如果您需要將枚舉更新為以下內容:

public enum TaskStatus
{
    NOTSET,
    UNINVOICED,
    INVOICED,
    SOMEOTHERSTATUSBETWEENINVOICEDANDPAID,
    PAID
}

然后,如果由int完成,則所有保留的數據都將重新定義。 曾經是UNINVOICED的現在將轉換為NOTSET,而曾經是PAID的現在已轉換為INVOICED。

並且,如果您通過服務接口公開您的內容,則根據技術的不同,它將為枚舉元素分配不同的int值。

也就是說,通過Web Reference公開的枚舉不會具有與通過Service Reference公開的枚舉相同的int值。

始終,將您的枚舉保留為字符串,並始終將其傳遞/按枚舉或字符串進行轉換。

作為一種更通用的方法,您可以創建將所有數字類型轉換為所需的任何枚舉類型的自定義方法:

static TEnum GetEnum<TEnum>(object obj)
    where TEnum : struct, IConvertible
{
    if (!typeof(TEnum).IsEnum)
        throw new ArgumentException("TEnum must be an enumerated type");                

    return (TEnum)(IConvertible)(Convert.ToInt32(obj));
}

其用法的簡單示例:

    enum Planet { Sun = 0, Moon = 1 }
    enum Abc { Abc5 = 0, Abc30 = 1 }

    private static void Main(string[] args)
    {
        var x = GetEnum<Planet>((long) 0);
        var y = GetEnum<Abc>((double)1);
        Console.Write(x);
        Console.Write(",  " + y);
    }

輸出:Sun,Abc30

暫無
暫無

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

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