枚举类型的通用签名

本文关键字:类型 枚举 | 更新日期: 2023-09-27 17:53:37

我在整个项目中定义了几个Enum类型,用于特定于对象的状态标识符:

  public enum ObjectAState
  {
    ObjectAAvailable,
    ObjectADeleteRequested,
    ObjectADeleted
  }
  public enum ObjectBState
  {
    ObjectBCreationRequested,
    ObjectBCreationFailed,
    ObjectBDeleteRequested,
    ObjectBDeleted
  }

任何使用ObjectA的人都只能引用ObjectA的枚举,所有其他对象也是如此——它们的枚举是隔离的,这使得它们更容易理解,因为不适用于对象的状态没有显示出来(这就是为什么我不把所有对象的所有状态都放在一个单独的enum中)。

对于给定的状态,有零个,一个或多个其他状态(在同一个enum内)可以遵循;根据定义,也有一些状态不能遵循。例如,在ObjectA中,状态可以从ObjectAAvailable过渡到ObjectADeleteRequested,从ObjectADeleteRequested过渡到ObjectADeleted,但不能直接从ObjectAAvailable过渡到ObjectADeleted。在每个对象中都有一段冗长而重复的代码来执行有效的状态转换,我想用一个方法来代替。

作为测试,我这样做了:

Dictionary<ObjectAState, List<ObjectAState>> Changes = new Dictionary<ObjectAState, List<ObjectAState>>();

这是一个通过ObjectAState作为键访问的Dictionary,持有List的其他ObjectAState值,这些值表示有效的转换填充如下:

Changes.Add(ObjectAState.ObjectAAvailable, new List<ObjectAState> { ObjectAState.ObjectADeleteRequested });
Changes.Add(ObjectAState.ObjectAADeleteRequested, new List<ObjectAState> { ObjectAState.ObjectADeleted });
Changes.Add(ObjectAState.ObjectADeleted, null);

我有一个简单的方法,看起来像这样:

public bool StateTransitionIsValid(ObjectAState currentState, ObjectAState targetState)
{
  return Changes[currentState].Contains(targetState);
}

这工作完美- ObjectA的用户只需传入对象的当前状态和目标状态的enum,并获得一个简单的true或false来判断转换是否有效。那么,如何使这个泛型,使相同的方法可以处理来自其他对象的枚举?

我试过了:

Dictionary<Enum, List<Enum>> Changes = new Dictionary<Enum, List<Enum>>();

编译没有错误-但是向Dictionary添加条目的代码失败:

Changes.Add(ObjectAState.ObjectAAvailable, new List<ObjectAState> { ObjectAState.ObjectADeleteRequested });
Error   1   The best overloaded method match for 'System.Collections.Generic.Dictionary<System.Enum,System.Collections.Generic.List<System.Enum>>.Add(System.Enum, System.Collections.Generic.List<System.Enum>)' has some invalid arguments
Error   2   Argument 2: cannot convert from 'System.Collections.Generic.List<MyApp.ObjectAState>' to 'System.Collections.Generic.List<System.Enum>'

我到处找了一遍,似乎看不出我做错了什么。有人知道为什么我的"通用"版本不能编译吗?

枚举类型的通用签名

您的方法或类必须是泛型定义的,这样您才能有一个实际的泛型类型来使用。

困难在于没有办法在编译时完全强制泛型类型为Enum。这可能是你最接近的了:
public class MyTestClass<T>
    where T : struct, IConvertible // Try to get as much of a static check as we can.
{
    // The .NET framework doesn't provide a compile-checked
    // way to ensure that a type is an enum, so we have to check when the type
    // is statically invoked.
    static EnumUtil()
    {
        // Throw Exception on static initialization if the given type isn't an enum.
        if(!typeof (T).IsEnum) 
            throw new Exception(typeof(T).FullName + " is not an enum type.");
    }
    Dictionary<T, List<T>> Changes = new Dictionary<T, List<T>>();
    ...
}

我认为这是因为你试图使用非通用对象,虽然定义是通用的。试试这个。

Changes.Add(ObjectAState.ObjectAAvailable, new List<Enum> { ObjectAState.ObjectADeleteRequested });