C# 物体反射#

C# 物体反射#,c#,C#,我想用一行代码生成正确的对象,而不是开关,因为每次添加新设备时,我都必须添加一行代码 在没有开关箱的情况下,是否可以在一条线路上进行此操作 public static Device GetDevice(Device.enumDevice TypeOfDevice, string alias) { // Create the Object with using reflection switch (TypeOfDevice) { case Device.e

我想用一行代码生成正确的对象,而不是开关,因为每次添加新设备时,我都必须添加一行代码

在没有开关箱的情况下,是否可以在一条线路上进行此操作

public static Device GetDevice(Device.enumDevice TypeOfDevice, string alias)
{
    // Create the Object with using reflection

    switch (TypeOfDevice)
    {
        case Device.enumDevice.A34411:
            return new A34411(string alias);
            break;
        case Device.enumDevice.N5744:
            return new N5744(string alias);
            break;
        default:
            throw new NotImplementedException();
    }

    return null;
}

优雅的方法是将依赖项注入与“命名类型注册”一起使用。

优雅的方法是将依赖项注入与“命名类型注册”一起使用。

您可以将工厂方法作为代理存储在字典中

private static Dictionary<Device.enumDevice, Func<string, Device>> _factoryDict =
    new Dictionary<Device.enumDevice, Func<string, Device>>{
        [Device.enumDevice.A34411] = (alias) => new A34411(alias),
        [Device.enumDevice.N5744] = (alias) => new N5744(alias),
    };

...

public static Device GetDevice(Device.enumDevice TypeOfDevice, string alias)
{
    if (_factoryDict.TryGetValue(TypeOfDevice, out var factory)) {
        return factory(alias);
    }
    throw new NotImplementedException();
    // No retun statement here, as it would be unreachable because of the throw statement.
}

可以将工厂方法作为委托存储在字典中

private static Dictionary<Device.enumDevice, Func<string, Device>> _factoryDict =
    new Dictionary<Device.enumDevice, Func<string, Device>>{
        [Device.enumDevice.A34411] = (alias) => new A34411(alias),
        [Device.enumDevice.N5744] = (alias) => new N5744(alias),
    };

...

public static Device GetDevice(Device.enumDevice TypeOfDevice, string alias)
{
    if (_factoryDict.TryGetValue(TypeOfDevice, out var factory)) {
        return factory(alias);
    }
    throw new NotImplementedException();
    // No retun statement here, as it would be unreachable because of the throw statement.
}

快速,但不是一个完整的示例:

public abstract class Device
{
    protected Device(string alias)
    {
        Alias = alias;
    }
    public string Alias { get; }
}

public class A1 : Device
{
    public A1(string alias) : base(alias) { }
}

public class A2 : Device
{
    public A2(string alias) : base(alias) { }
}

class DeviceAttribute : Attribute
{
    public DeviceAttribute(Type type)
    {
        Type = type;
    }

    public Type Type { get; }
}

public enum DeviceEnum
{
    [Device(typeof(A1))]
    A1,
    [Device(typeof(A2))]
    A2
}

public static class DeviceEnumExtension
{
    public static Device GetInstance(this DeviceEnum obj, string alias)
    {
        var member = typeof(DeviceEnum).GetMember(obj.ToString());

        if (member[0].GetCustomAttributes(typeof(DeviceAttribute), false)[0] is DeviceAttribute deviceAttr)
        {
            var ctor = deviceAttr.Type.GetConstructor(new[] {typeof(string)});
            return ctor.Invoke(new object[] {alias}) as Device;
        }
        return null;
    }
}

public class UnitTest1
{
    [Fact]
    public void Test1()
    {
        // Arrange
        var a1 = DeviceEnum.A1;
        var a2 = DeviceEnum.A2;

        // Act
        var instanceA1 = a1.GetInstance("A1");
        var instanceA2 = a2.GetInstance("A2");

        // Assert
        Assert.Equal(typeof(A1), instanceA1.GetType());
        Assert.Equal(typeof(A2), instanceA2.GetType());
        Assert.Equal("A1", instanceA1.Alias);
        Assert.Equal("A2", instanceA2.Alias);
    }
}

快速,但不是一个完整的示例:

public abstract class Device
{
    protected Device(string alias)
    {
        Alias = alias;
    }
    public string Alias { get; }
}

public class A1 : Device
{
    public A1(string alias) : base(alias) { }
}

public class A2 : Device
{
    public A2(string alias) : base(alias) { }
}

class DeviceAttribute : Attribute
{
    public DeviceAttribute(Type type)
    {
        Type = type;
    }

    public Type Type { get; }
}

public enum DeviceEnum
{
    [Device(typeof(A1))]
    A1,
    [Device(typeof(A2))]
    A2
}

public static class DeviceEnumExtension
{
    public static Device GetInstance(this DeviceEnum obj, string alias)
    {
        var member = typeof(DeviceEnum).GetMember(obj.ToString());

        if (member[0].GetCustomAttributes(typeof(DeviceAttribute), false)[0] is DeviceAttribute deviceAttr)
        {
            var ctor = deviceAttr.Type.GetConstructor(new[] {typeof(string)});
            return ctor.Invoke(new object[] {alias}) as Device;
        }
        return null;
    }
}

public class UnitTest1
{
    [Fact]
    public void Test1()
    {
        // Arrange
        var a1 = DeviceEnum.A1;
        var a2 = DeviceEnum.A2;

        // Act
        var instanceA1 = a1.GetInstance("A1");
        var instanceA2 = a2.GetInstance("A2");

        // Assert
        Assert.Equal(typeof(A1), instanceA1.GetType());
        Assert.Equal(typeof(A2), instanceA2.GetType());
        Assert.Equal("A1", instanceA1.Alias);
        Assert.Equal("A2", instanceA2.Alias);
    }
}

您可以在类上放置一个自定义属性,并使用反射,枚举
设备
基类的所有子类,查找具有正确值的属性。因此,您的计划是也删除enum的使用?
返回新的A34411(字符串别名)此语法不正确。删除
字符串
。此外,最后的
返回null
也可能是重复的,因为无法访问。所有可能的路径都以交换机的一个分支结束,每个分支都返回或抛出异常。您可以在类上放置自定义属性,并使用反射枚举
设备
基类的所有子类,正在查找具有正确值的属性。因此,您的计划是也删除枚举的使用?
返回新的A34411(字符串别名)此语法不正确。删除
字符串
。此外,最后的
返回null
也可能是重复的,因为无法访问。所有可能的路径都以交换机的一个分支结束,每个分支都返回或抛出异常。第二个示例不正确。Type.GetType在最简单的情况下需要“namespace.class”,但最好使用完整的AssemblyQualifiedName。@arndtdv:你说得对。如果类位于同一程序集中,则可以省略AssemblyQualifiedName。第二个示例不正确。Type.GetType在最简单的情况下需要“namespace.class”,但最好使用完整的AssemblyQualifiedName。@arndtdv:你说得对。如果这些类位于同一程序集中,则可以省略AssemblyQualifiedName。