繁体   English   中英

对象反射C#

[英]Object reflection c#

我想用一条代码行而不是开关盒来生成正确的对象,因为总是在添加新设备时必须添加新行。

是否可以在没有开关盒的情况下在一行中完成此操作?

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.
}

或者,使用反射:

const string deviceNameSpace = "MyName.MyProject.Devices.";

public static Device GetDevice(Device.enumDevice deviceType, string alias)
{
    string typeName = deviceNameSpace + deviceType.ToString();
    Type type = Type.GetType(typeName, throwOnError: true);
    return (Device)Activator.CreateInstance(type, 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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM