2013-04-14 4 views
1

У меня есть несколько внешних устройств, с которыми я могу общаться через общий API.Определить необходимый класс динамически

string busIdentifier = "BUS:0:1"; 
var dev = new CommonDeviceDriver(busIdentifier); 

Теперь я могу запросить устройство:

string identifier = dev.QueryIdentifier(); 

Теперь у меня есть несколько конкретных драйверов, например ConcreteDeviceA, ConcreteDeviceB и ConcreteDeviceC. Каждый из драйверов устройства должен иметь «идентификатор».

Теперь я хочу загрузить правильный драйвер устройства для этого ранее запрошенного идентификатора.

Как с этим связаться C#?

Исходя из python я хотел бы сделать что-то вроде этого:

# Have a dictionary where key is identifier and value is the class 
supported_devices = {ConcreteDeviceA.identifer : ConcreteDeviceA, 
        ConcreteDeviceB.identifer : ConcreteDeviceB, 
        ConcreteDeviceC.identifer : ConcreteDeviceC} 
busIdentifier = "BUS:0:1" 
dev = CommonDeviceDriver(busIdentifier) 
identifier = dev.QueryIdentifier() 
concrete_device = supported_devices[identifier](dev) # Get class and call constructor 
+0

В чем же ваша проблема? Часть словаря? Что вы пробовали на C#? – LightStriker

+0

Ну, есть несколько;). В этом примере «python» все устройства Concrete реализуют интерфейс, гарантирующий, что у них есть статический член «dentifier» -> «static properties» с интерфейсом невозможно. Как создать такое поведение на C#? – Razer

+1

Ну, я вижу, что вы хотите ... В C#, когда вы хотите добавить «идентификацию» к классу, вы не можете сделать это, используя статическое свойство. Однако то, что вы можете сделать, это добавить атрибут в класс, который может хранить данные, относящиеся к этому классу. – LightStriker

ответ

2

Самый простой способ сделать это было бы factory method. Если вы знаете доступные типы во время компиляции, вы можете просто перечислить их в коде.

public static DriverBase CreateDriver(string identifier, object device) { 
    switch (identifier) { 
    case IDENTIFIER_A: return new ConcreteDeviceA(device); 
    // etc 
    } 
} 

Если вы не знаете всех типов во время компиляции (или вы действительно возражают против использования выше), то вы можете использовать отражение. Тогда вы можете по существу иметь идентификатор сопоставления словаря для ввода типа (как у вас есть в Python) и создать экземпляр объекта либо с помощью Activator.CreateInstance, либо самостоятельно просмотрев его конструктор. В этом случае вам придется отбрасывать возвращаемый объект базовому типу.

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