![](/img/trans.png)
[英]C# - String.GetHashCode() -> don't use as unique identifier
[英]Switchable Unique Identifier in C#
我正在實現一個系統,以在正在編寫的程序的不同部分之間發送消息。 有一些通用的消息類型,以及某些特定於程序各部分的消息。 我想避免從每種類型的基本消息類派生出固有的層次結構腐爛,因此我將這種類型封裝在int或ushort中。 然后,我使用“消息”名稱空間和帶有一堆常量的靜態類集中不同的類型。 但是,我遇到了必須為每個不同部分維護一個唯一編號列表的問題:
namespace Messages
{
public static class Generic
{
public const Int32 Unknown = 0;
public const Int32 Initialize = 1;
...
public const Int32 Destroy = 10;
}
}
然后在其他地方
namespace Messages
{
public static class Graphics
{
public const Int32 Unknown = 0;
public const Int32 AddGraphic = 11; // <-- ?
}
}
擁有一個任意的11似乎很困難,特別是如果我有幾個,維護和更新以確保沒有沖突似乎很痛苦。 是否有一個簡單的解決方案,以確保對此的每次引用都是唯一的? 我嘗試使用靜態只讀,從靜態構造函數中的Unique.ID()函數初始化它們,但是如果我這樣做,我將無法在傳遞的Message類型上切換(),因為它說“期望常量類型”對於每種情況。
您不使用枚舉是否有某些原因?
public enum MessageTypes
{
Unknown,
Initialize,
...
}
-編輯:
詳細闡述我的意見,考慮
enum MessageType
{
Update,
Delete,
Destroy
}
MessageType t = ...;
switch(t){
case MessageType.Update:
DoUpdate();
}
}
與:
interface IActionable
{
void Do ();
}
public abstract class ActionableBase : IActionable
{
// some other things
public abstract void Do ();
}
public class UpdateAction : ActionableBase
{
public override void Do ()
{
// Update Code
}
}
...
IActionable a = ...;
a.Do();
您可以為每個班級使用一個數字范圍。 為該類定義一個基數,並將0、1、2等添加到該基數。
如果要保持它們為數字,一種方法是將它們划分為不同的大小:
namespace Messages
{
public static class Generic
{
// these messages are 3-figure numbers
public const Int32 Unknown = 0;
public const Int32 Initialize = 101;
...
public const Int32 Destroy = 110;
}
public static class Graphics
{
// these messages are 4-figure numbers
public const Int32 Unknown = 0;
public const Int32 AddGraphic = 1001; // <-- ?
// and so on...
}
}
然后,您只需要確保每種消息都在邊界之內即可。
這不是自動的,但是將其復制到各處后可能更容易維護:
public enum Generic
{
Unknown = 0,
Initialize = 1,
Destroy = 10
}
public enum Graphics
{
AddGraphic = Generic.Destroy + 1
}
因此,您可以讓所有特定的枚舉都從上一個枚舉集中的值開始,然后像這樣建立它們。
在您的實際對象中,您可以將它們存儲為int,只需將任何枚舉值轉換為適當的int即可。
盡管在這種情況下繼承似乎是不可避免的,因為數據模型中存在自然的層次結構。
我建議您查找“命令”和“消息”之間的區別,這可能有助於您得出結論,即在消息中使用幻數\\枚舉是一個壞主意。
理想情況下,您想要創建由偵聽器觀察和操作的“命令”。
高溫超導
奧利
如果您確實要執行此操作,則可以創建一個通用私有枚舉來保存所有可能的值。
然后,您可以通過單獨的類將這些值公開為只讀屬性,這些屬性將枚舉公開為Int32s-例如
namespace Messages
{
private enum AllMessageTypes
{
Update,
Delete,
Destroy,
AddGraphic
}
public static class Generic
{
public Int32 Update
{
get { return (Int32)AllMessageTypes.Update; }
}
...
}
public static class Graphics
{
public Int32 AddGraphic
{
get { return (Int32)AllMessageTypes.AddGraphic ; }
}
}
}
但是-我建議您重新設計解決方案。 這似乎是在自找麻煩(我敢肯定人們會對此發表評論)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.