2012-05-03 1 views
0

У нас есть класс 'SomeClass':С # добавить константные атрибуты поля с помощью

namespace Namespace 
{ 
    class SomeClass 
    { 
     // something 
    } 
} 

И атрибут 'SomeAttribute':

class SomeAttribute : System.Attribute { } 

Задача: добавить ко всему рынку классов по SomeAttribute «общественность const string Type. Модифицированные классы должны быть следующие:

class SomeClass 
{ 
    // something 
    public const string Type = @"Namespace.SomeClass"; 
} 

UPD:

Я использую следующий подход для обработки сообщения:

class Manager 
{ 
    // message has 3 parts: 
    // string message = String.Format("{0}{1}{2}", 
    //  typeof(SomeClass).ToString(), 
    //  splitter, 
    //  Manager.Serialize(someClassObj) 
    //) 
    public static string GetType(string message) { /* some code */ } 
    public static string Serialize(SomeClass message) { /* XML serialization */ } 
    public static SomeClass Deserialize(string message) { /* deserialization */ } 
} 

class Logic 
{ 
    public void ProcessMessage(string message) 
    { 
     switch (Manager.GetType(message)) 
     { 
      case SomeClass.Type: 
       { 
        SomeClass msg = Manager.Deserialize(message) as SomeClass; 
        // send message to binded objects 
       } 
       break; 
      case ClassInheritedFromSomeClass.Type: 
       { 
        // the same 
       } 
       break; 
      // etc. 
     } 
    } 
} 

UPD 2:

Подробнее о сообщениях , В это время я использую следующий подход:

public class BaseMessage 
{ 
    public const string Type = @"Messages.BaseMessage"; 
} 

public class LoginMessage : BaseMessage 
{ 
    public new const string Type = @"Messages.Client.LoginMessage"; 

    public string Nickname { get; set; } 
    public string Password { get; set; } 
} 

Заключения

Я думаю, что лучший случай, чтобы изменить Manger так:

class Manager 
{ 
    // create event table 

    public Action<BaseMessage> this[string eventName] 
    { 
     get 
     { 
      if (!m_eventTable.ContainsKey(eventName)) 
      { 
       m_eventTable.Add(eventName, new Action<BaseMessage>(message => { })); 
      } 
      return m_eventTable[eventName]; 
     } 
     set 
     { 
      m_eventTable[eventName] = value; 
     } 
    } 

    public void Send(BaseMessage message, string messageName) 
    { 
     if (m_eventTable.ContainsKey(messageName) && this[messageName].Method != null) 
     { 
      this[messageName].Invoke(message); 
     } 
    } 

    private Dictionary<string, Action<BaseMessage>> m_eventTable = new Dictionary<string, Action<BaseMessage>>(); 
} 
+1

Зачем вам это нужно? 'typeof (SomeClass)' намного более универсален ...? Например, 'typeof (SomeClass) .FullName' –

+0

И если значение константы отличается от' typeof (SomeClass) .FullName': Почему бы не поместить значение непосредственно в атрибут? – dtb

+0

Атрибуты - это вещи Reflection. То, что вам нужно, может быть больше похоже на свойство в базовом классе, возвращающее GetType(). FullName'. – fero

ответ

0

Использование switch с GetType неправильным путем для реализации полиморфизма, поскольку он проверяет только наиболее производный класс (разрывает расширяемость).

В вашем конкретном случае, где вы должны отвечать за поведение Manager, вы можете использовать ключевое слово dynamic и перегруженные методы. Но это снова нарушит SOLID, потому что он не открыт для расширения.

Вместо того, чтобы нарушать SOLID таким образом, попробуйте найти способ использования виртуальных методов для выполнения действия, специфичного для конкретного типа.

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

  • Нет связанных вопросов^_^