将抽象设备库从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));
        }
    }
}

将抽象设备库从python迁移到c#

我已经编辑了我的答案,请查收。这也是一个草图。我希望这对你有帮助。

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();
        }   
    }
}