2011-04-26 181 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