枚举类型的通用签名
本文关键字:类型 枚举 | 更新日期: 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 });