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。