2011-12-21 2 views
2

У меня есть интерфейс с именем IDeviceId, который я использую в своем домене. У меня также есть несколько конкретных классов, которые реализуют IDeviceId. Каждый конкретный класс содержит логику для определенного типа DeviceId. Например, у меня есть DeviceMacId, который является просто действительным MAC-адресом. Другим конкретным классом является DeviceShortMacId, который принимает последние 6 цифр действительного MAC-адреса и объединяет его с фиксированным 6-символьным префиксом для создания действующего MAC (несколько устаревших приложений используют только последние 6 цифр). У меня есть несколько других классов для выражения идентификатора, но большинство из них являются производными от одних и тех же данных.Как преобразовать один объект в другой?

Я хотел бы иметь возможность легко конвертировать из любого из этих классов в другой. Моя первая мысль заключалась в том, чтобы создать статический класс и сделать что-то вроде DeviceIdConverter.ToDeviceShortMacId (IDeviceId).

Каким образом можно легко принимать данные в одной форме, а затем конвертировать их в другую с возможностью повторяемости (через несколько приложений)?

ответ

3

Я не думаю, что для этого есть «лучший способ», вам нужно будет найти шаблон, который будет работать для вас и идти с ним.

Off верхней части моей головы, основываясь на примерах, вы представили бы я сделал что-то вроде:

interface IDeviceId 
{ 
    // Other methods 
    IDeviceId ToDeviceShortMacId(IDeviceId); 
    IDeviceId ToDeviceMacId(IDeviceId); 
    // etc... 
} 

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

public static class MacDeviceIdExtensions 
{ 
public static DeviceMacId ToDeviceMacId(this IDeviceId deviceId) 
{ 
    // Implement conversion 
} 
public static DeviceShortMacId ToDeviceMacId(this IDeviceId deviceId) 
{ 
    // Implement conversion 
} 
} 

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

+0

Мое конечное решение оказалось более сложным (и довольно специфичным для домена), но этот подход лучше всего подходит для меня. Множество хороших вариантов в этой теме помимо этого. – GregB

2

Почему бы вам просто не создать конструкторы на всех ваших реализациях класса IDeviceID, которые принимают объект IDeviceID.

DeviceMacID macID = new DeviceMacID(...whatever you do normally...); 
DeviceShortMacID shortMacID = new DeviceShortMacID((IDeviceID)macID); 

Пример кода

public DeviceShortMacID : IDeviceID 
{ 
    private ID _ID; 
    public DeviceShortMacID() { } 
    public DeviceShortMacID(IDeviceID id) 
    { 
     if (id is DeviceshortMacID) 
      this._ID = id.GetID(); 
     else 
      this._ID = this.ConvertFrom(id); 
    } 

    public ID ConvertFrom(IDeviceID oldID) { ... convert code ...} 
    public ID GetID() { return this_ID; } 
} 

public interface IDeviceID 
{ 
    public ID GetID(); 
    public ID ConvertFrom(IDeviceID oldID); 
} 

public class ID { } // I don't know what you return so I'm making up this class 
+0

Разве у меня тогда не было бы логики для перехода от одного класса к другому в каждом конкретном классе?Я думал, что будет легче поддерживать, если бы вся моя логика конверсии находилась в одном месте (один класс для редактирования, если я добавляю новый конкретный класс или должен обновлять все мои конкретные классы). – GregB

+0

Единственная логика, в которой вы должны нуждаться в каждом классе, - это код для того, как он принимает идентификатор genev IDID и создает свой собственный идентификатор. Если это важно, переданы ли вы в DeviceMacID или DeviceShortMacID, я не думаю, что ваш интерфейс определен правильно. –

3

Одной из возможностей было бы реализовать свой собственный кастинг:

public static explicit operator DeviceShortMacId(DeviceMacId deviceMacID) 
{ 
    return new DeviceShortMacId(deviceMacID.MacAddress); 
} 

public static explicit operator DeviceMacId(DeviceShortMacId deviceShortMacID) 
{ 
    return new DeviceMacId(deviceShortMacID.MacAddress); 
} 

Таким образом, вы можете сделать:

DeviceMacId newDeviceId = (DeviceShortMacId)deviceMacID 

При таком подходе, если некоторые конверсии невозможно, вы можете справиться с этим сами и бросить InvalidCastException.

+0

Оператор 'as' не использует * неявные операторы. Он будет * не * конвертировать тип. Подумайте, 'a is Type? (Type) a: null', но без явного приведения. –

+0

Справа. Забыл. Благодарю. И сделать их ясными для хорошей меры. Этот материал не может быть имплицитным. – MPelletier

+0

Действительно! Upvoted. –

2

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

+1

На мой взгляд, это не старомодно, это модно. – MPelletier

+0

upvote для подсказки методов расширения;) – Adam

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