将通用枚举参数转换为可为空的long时出现异常

时间:2014-08-28 19:20:42

标签: c# generics enums

我有以下通用方法,我希望封装一些执行以下操作的逻辑:获取ILookUp的实例(这是我自己的通用接口类型),如果实例为null,则调用带有null参数的方法,如果不为null,则使用接口中ID字段的值调用相同的方法。

ID字段始终是基于ulong的枚举类型。 ID字段永远不会为空,我仍然希望将其转换为可以为空的类型。

但是,我在指定的语句中得到InvalidCastException。奇怪的是,在Watch窗口中,演员阵容很好。可能出现什么问题......?

   /// <summary>
   /// if not null, extracts an ID and snapshots it as a nullable ulong (ulong?)
   /// </summary>          
   public Id? SnapshotID<T, Id>(T instance)
     where T : ILookUp<T, Id>
     where Id : struct // is always an enum based on ulong
   {
      if (instance != null)
        {
            ulong? enumAsULong = (ulong?)((ValueType)instance.ID); // <- InvalidCastException here

            return (Id?)(ValueType)DoEnumNullable(enumAsULong);
        }
        else
        {
            return (Id?)(ValueType)DoEnumNullable((ulong?)null);
        }
    }

    public ulong? DoEnumNullable(ulong? val)
    {
        return DoUInt64Nullable(val);
    }

    public interface ILookUp<T,Id> 
        where T : ILookUp<T,Id>
        where Id : struct  // cannot specify enum - this allows nullable operations on       Id enums
    {

        Id ID { get; }
    }

1 个答案:

答案 0 :(得分:1)

你不能这样做。 You can only cast a boxed value type to the same type or Nullable<T>。在这种情况下,您可以将其转换为T? Nullable<YourEnumType>,而不是其他类型。

以下应该工作。

ulong? enumAsULong = (ulong)((ValueType)instance.ID);

ulong? enumAsULong = Convert.ToUInt64((ValueType)instance.ID);