将抽象设备库从python迁移到c#
本文关键字:python 迁移 抽象 | 更新日期: 2023-09-27 18:03:17
我来自python
,刚到C#
。我正在将设备库迁移到c#。库本身包含所有设备实现,并管理设备的创建。下面是一些python代码:
# All supported devices must be added to this list
device_table = [DeviceA, DeviceB, DeviceC, DeviceD]
def DeviceFactory(device, identifier):
"""
Returns an open device for the given identifier. If there is no proper
driver it raises an NotImplementedError. If wrong device connected to
port a ValueError is raised
"""
assert type(identifier) == str
if device not in device_table:
# Device not found in device table, so it's not implemented
raise NotImplementedError("No device driver implemented for "
"identifier {0}.".format(identifier))
# If no identifier selected, do configuration before
if identifier == "":
raise AttributeError("No identifier selected.")
# Try to open a device and then read identifier
try:
dev = DevIOLib.open(identifier)
dev_identifier = dev.ask_identifier()
dev.close()
except Exception:
raise DeviceError("Error opening device {0} on {1}.".format(device.name(),
identifier))
# Now check if the opened device is really the right one
if re.match(device.get_idn_regex(), dev_identifier) is not None:
return device(identifier)
raise ValueError("Wrong device connected to identifier {0}.".format(identifier))
Device[A-D]
为混凝土装置的实现。你现在可以创建一个设备:
concrete_device = DeviceFactory(DeviceC, "devicePortC")
我经历过这个模式工作得很好,所以我想在C#
中做一个类似的模式。正如您所看到的,实现是非常动态的。你如何在c#中实现它呢?
因此,所有的设备实现和管理都应该进入一个类库,以便在其他项目中轻松使用设备。
这个问题有更好的解决方法吗?
在帮助下,我可以创建以下c#
public class DeviceFactory
{
private static List<Type> device_table = new List<Type>() { typeof(DeviceA)};
public static Device CreateDevice(Type deviceType, string devicePort)
{
if (string.IsNullOrEmpty(devicePort))
{
throw new ArgumentException("No identifier selected.");
}
if (!deviceType.IsSubclassOf(typeof(Device)))
{
throw new ArgumentException("Device type unknown.");
}
if (!device_table.Contains(deviceType))
{
var message = string.Format("No device driver implemented for identifier {0}.", devicePort);
throw new NotImplementedException(message);
}
string dev_identifier;
DevHandle dev_handle;
try
{
dev_handle = DevManager.Open(devicePort));
dev_identifier = dev_handle.AskIdentifier();
}
catch (Exception)
{
throw new Exception(string.Format("Error opening device on {0}.", devicePort));
}
var idn_property = deviceType.GetProperty("Identifier", BindingFlags.Static);
var match = Regex.Match(dev_identifier,
idn_property.GetValue(null, null).ToString());
if (match.Success)
{
return (VisaDevice) Activator.CreateInstance(deviceType, dev_handle);
}
else
{
dev_handle.IO.Close();
var dev_name = deviceType.GetProperty("Name", BindingFlags.Static).GetValue(null, null).ToString();
throw new Exception(string.Format("Wrong device connected to port {0}. " +
"Expected device {1}", devicePort, dev_name));
}
}
}
我已经编辑了我的答案,请查收。这也是一个草图。我希望这对你有帮助。
namespace DeviceCreation
{
//public enum DeviceType { DeviceA, DeviceB, DeviceC, DeviceD };
public abstract class Device
{
public string Identifier { get; private set; }
public Device(string identifier)
{
Identifier = identifier;
}
public abstract string Name();
public virtual void Close()
{
}
public string AskIdentifier()
{
return Identifier;
}
public static string GetIdentifierPattern()
{
return "xyzsdfsdf";
}
}
public class DeviceA : Device
{
public DeviceA(string identifier) : base(identifier) { }
public override string Name()
{
return "DeviceA";
}
}
public class DeviceB : Device
{
public DeviceB(string identifier) : base(identifier) { }
public override string Name()
{
return "DeviceB";
}
}
public class DeviceC : Device
{
public DeviceC(string identifier) : base(identifier) { }
public override string Name()
{
return "DeviceC";
}
}
public class DeviceD : Device
{
public DeviceD(string identifier) : base(identifier) { }
public override string Name()
{
return "DeviceD";
}
}
public class DeviceFactory
{
private static List<Type> device_table = new List<Type>() { typeof(DeviceA), typeof(DeviceB), typeof(DeviceC), typeof(DeviceD) };
public static Device Create(Device device, string identifier)
{
if (!device_table.Contains(device.GetType()))
{
var message = string.Format("No device driver implemented for identifier {0}.", identifier);
throw new NotImplementedException(message);
}
if (string.IsNullOrEmpty(identifier))
throw new ArgumentException("No identifier selected.");
//Try to open a device and then read identifier
string dev_identifier;
try
{
var dev = DevIOLib.Open(identifier);
dev_identifier = dev.AskIdentifier();
dev.Close();
}
catch (Exception ex)
{
throw new Exception(string.Format("Error opening device {0} on {1}.", device, identifier));
}
var match = Regex.Match(dev_identifier, Device.GetIdentifierPattern());
if (match.Success)
{
var newDevice = (Device) Activator.CreateInstance(device.GetType(), dev_identifier);
return newDevice;
}
else
throw new Exception(string.Format("Wrong device connected to identifier {0}.", identifier));
}
}
public static class DevIOLib
{
public static Device Open(string identier)
{
return new DeviceA(identier);
}
}
public class DeviceCreationTest
{
public static void Main(string[] args)
{
var d = new DeviceA("asdfsdf");
DeviceFactory.Create(d, "asdfsdf");
Console.ReadKey();
}
}
}