2009-09-02 3 views
1

Я реализую систему для отправки сообщений между различными частями программы, которую я пишу. Существуют некоторые общие типы сообщений, а также некоторые специфические для каждой части программы. Я хотел бы избежать иерархии rot, присущей генерации базового класса сообщений для каждого типа. Поэтому я инкапсулирую этот тип в int или ushort. Затем я централизую различные типы с пространством имен «Сообщения» и статическим классом с кучей констант. Тем не менее, я столкнулся с вопросом о необходимости поддерживать список уникальных номеров для каждого отдельного раздела:Переключаемый уникальный идентификатор в C#

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 кажется сложным, особенно, если у меня есть несколько они, поддерживая и обновляя, чтобы убедиться, что столкновений нет, кажется, боль. Есть ли простое решение, чтобы убедиться, что каждая ссылка на это уникальна? Я попытался использовать статический readonly, инициализируя их функцией Unique.ID() в статическом конструкторе, но если я это сделаю, то я не могу переключить() по переданному типу сообщения, так как он говорит: «Ожидается постоянный тип», для каждого случая.

+0

Что-то не так с просто объектами? public static readonly object AddGraphic = new object(), каждый становится уникальным (по крайней мере, во время выполнения)? – meandmycode

+0

Я не могу переключиться на основе значения readonly. Я все равно переосмысливаю свой проект. – Quantumplation

ответ

7

Есть ли причина, по которой вы не используете перечисления?

public enum MessageTypes 
{ 
    Unknown, 
    Initialize, 
    ... 
} 

- Edit:

Конкретизируя мой комментарий, Рассмотрим

enum MessageType 
{ 
    Update, 
    Delete, 
    Destroy 
} 

MessageType t = ...; 

switch(t){ 
    case MessageType.Update: 
     DoUpdate(); 
    } 
} 

Versus:

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

Перечисление не позволило мне «очертить» декларацию разных типов сообщений. переключатель (сообщение.Тип) { &hl=ru Дело в том, что сообщения. Генерация. Инициализация: перерыв; case Messages.Graphics.AddGraphic: break; } – Quantumplation

+0

(er, форматирование получилось странным, но я уверен, что вы поняли эту идею.) – Quantumplation

+0

Вы сказали в своем посте, что не хотите иерархии классов, теперь вы хотите? Если честно, если ваш оператор switch настолько велик, я бы сказал, что вам, вероятно, стоит подумать о том, как сделать свой дизайн более OO. –

1

Вы можете использовать диапазон номеров для каждого класса. Определите базовое число для класса и добавьте 0, 1, 2 и т. Д. К этому базовому номеру.

1

Если вы хотите, чтобы держать их числовые один путь, чтобы разделить их на разные величины:

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... 
    } 

} 

Тогда вам просто необходимо, чтобы убедиться, что вы держите в пределах границ для каждого типа сообщения.

1

Это не является автоматическим, но это может быть немного легче поддерживать скопировав значения везде:

public enum Generic 
    { 
     Unknown = 0, 
     Initialize = 1, 
     Destroy = 10 
    } 

    public enum Graphics 
    { 
     AddGraphic = Generic.Destroy + 1 
    } 

Таким образом, вы можете иметь все ваши конкретные перечисления начинают со значением из предыдущего перечисления установить и построить их так.

В ваших реальных объектах вы можете сохранить их как int и просто преобразовать любое значение enum в соответствующий int.

Хотя, кажется, что наследование может быть неизбежным в этом случае, поскольку в вашей модели данных есть естественная иерархия.

+0

Почему wouuldn't AddGraphic просто будет другим вариантом в Generic перечислении? –

+0

Тейлор: Я ищу децентрализовать типы сообщений, так что разные системы определяют их собственные типы сообщений. – Quantumplation

+0

@ Тейлор, чтобы он мог передавать как Generic.Value, так и Graphics.Value в тот же метод и не иметь перекрывающиеся значения (например, Generic.Unknown и Graphics.AddGraphic были бы равны 0) –

0

Предлагаю вам найти разницу между 'command' & 'message', это может помочь вам прийти к выводу, что использование магических чисел \ enums внутри сообщений - плохая идея.

В идеале вы хотите создать «команды», которые наблюдаются и действуют слушателями ...

НТН

Олли

0

Если вы действительно, действительно хотите сделать это, вы можете создать один общий частный Enum, который содержит все возможные значения.

Затем вы можете вывести эти значения через свои отдельные классы как свойства только для чтения, которые отображают перечисления как 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 ; } 
     } 
    } 
} 

Тем не менее - я бы порекомендовал вам изменить свое решение. Кажется, что вы просите о неприятностях (как я уверен, люди будут комментировать)

+0

Да. Я думаю, что я буду создавать идентификатор by && вместе «SystemID» и «CommandID» (00010000 && 0001). То есть, если я не нахожу переработанное решение, которое мне нравится. – Quantumplation

Смежные вопросы