为什么我不能将整数转换为枚举

时间:2016-08-22 16:21:06

标签: c# enums

我正在尝试从DataGridViewRow单元格值中转换一个整数,我已经确认它等于0

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

InvalidCastException in Visual Studio

以下是创建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
}

4 个答案:

答案 0 :(得分:6)

我测试了一下,观察到如果原始值为Int32,则转换成功但如果(例如)Int64byte则失败。< / p>

我的建议解决方案是在演员表之前使用Convert.ToInt32()

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

来自MSDN

  

枚举是一组命名常量,其基础类型是任何整数类型。如果没有显式声明底层类型,则使用Int32。

因此,TaskStatus枚举来自Int32直接来自任何其他整数类型的强制转换将失败。

答案 1 :(得分:1)

这有效,但如果这是我可能要退休C#的唯一方法。

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

答案 2 :(得分:1)

作为旁注。当你使用枚举时,你应该使用该枚举的字符串,当通过服务持久化或公开时。

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现在已经发明了。

如果您通过服务接口公开,根据技术,它将以不同方式分配枚举元素的int值。

也就是说,通过 Web Reference 公开的枚举不会与通过服务参考公开的枚举具有相同的int值。

总是,将你的枚举保存为字符串并始终传递它/通过枚举或字符串转换它。

答案 3 :(得分:0)

作为一种更通用的方法,您可以创建自定义方法,将所有数字类型转换为您需要的任何枚举类型:

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