2011-04-26 179 views
1

我已经在我的项目中定义了几个Enum类型,用于特定对象的状态标识符通用签名:为枚举类型

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

任何使用对象A只能参照对象A枚举,和同样是所有的真其他对象 - 他们的枚举是孤立的,这使得他们更容易,因为它不适用于未显示的对象的状态来了解(这就是为什么我不只是把所有对象的所有状态在一个单一的enum)。

对于给定的状态下,存在零,一个或多个其他状态(在同一enum),其可以按照;根据定义,也有一些国家不能遵循。例如,在ObjectA中,状态可以从ObjectAAvailable转变为ObjectADeleteRequested,并且从ObjectADeleteRequested转变为ObjectADeleted,但不是直接从ObjectAAvailable转变为ObjectADeleted。中的每个对象有一个代码繁琐和重复比特来执行有效的状态转换,这是我想用一个单一的方法来代替。

作为测试,我这样做:

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

这是经由ObjectAState访问作为密钥的Dictionary,保持从而其他ObjectAState值,其表示有效转换的List填充:

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

这完美的作品 - 对象A的用户只需通过在对象的当前和目标状态的enum并得到一个简单的真或假的过渡是否有效。那么,如何使这个通用的,以便相同的方法可以处理其他对象的枚举?

我尝试这样做:

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

它编译没有错误 - 但条目添加到字典中的代码失败:

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>' 

我已经绕狩猎似乎并不能看看我做错了什么。任何人有任何想法,为什么我的'通用'版本不编译?

回答

1

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

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

这正是我所需要的 - 现在我明白了,这很明显。卫生署! – 2011-04-27 09:29:33

3

你的方法或类必须总体定义,让你有一个实际的泛型类型的工作。

难点在于在编译时没有办法完全实现泛型类型是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>>(); 
    ... 
} 
+0

可以稍微进一步针下来:'其中T:结构,IComparable的,IConvertible,IFormattable' – LukeH 2011-04-26 16:04:33

+0

它看起来像这样的答案是关于设法确保泛型类型是一个枚举?如果是这样,那真的不是我的问题 - 我没有试图强制Enum类型,只有通用定义工作*与* Enum。无论如何,这可能会在别处有用。 – 2011-04-27 09:32:31