【发布时间】:2017-12-22 12:44:08
【问题描述】:
我正在尝试看起来像这样的东西:
class SerialEquipment
{
private int baudrate;
......
public SerialEquipment(int baudrate)
{
this.baudrate= baudrate;
}
public int Baudrate{ get => baudrate; set => baudrate= value; }
......
public static void IdentifyEquipment<EquipmentType>()
{
int baudrate = (int)typeof(EquipmentType).GetProperty("Baudrate", BindingFlags.Static | BindingFlags.Public).GetValue(null, null);
........
}
}
class EquipmentTypeA: SerialEquipment
{
private static readonly int baudrate = 9600;
......
public EquipmentTypeA() : base(baudrate) { }
public static new int Baudrate{ get => baudrate}
......
}
class EquipmentTypeB : SerialEquipment
{
private static readonly int baudrate = 38400;
......
public EquipmentTypeB () : base(baudrate) { }
public static new int Baudrate { get => baudrate }
......
}
但是继承的目的是避免冗余,我找不到更好的东西来使用。我找不到只有一个声明的方法。那么有没有更好的方法来实现呢?
编辑 2018 年 3 月 1 日:
使用静态识别设备的功能如下所示:
public static List<String> IdentifyEquipment<EquipmentType>()
{
List<String> wantedEquipmentList = new List<String>();
int baudrate = (int)typeof(EquipmentType).GetProperty("Baudrate", BindingFlags.Static | BindingFlags.Public).GetValue(null, null);
String identificationCommand = (int)typeof(EquipmentType).GetProperty("Baudrate", BindingFlags.Static | BindingFlags.Public).GetValue(null, null);
String correctIdentificationResponse = (String)typeof(EquipmentType).GetProperty("CorrectIdentificationResponse", BindingFlags.Static | BindingFlags.Public).GetValue(null, null);
foreach (String aSerialPort in SerialPort.GetPortNames())
{
SerialPort deviceInTest = new SerialPort(aSerialPort, baudrate);
deviceInTest.Open();
deviceInTest.WriteLine(identificationCommand);
System.Threading.Thread.Sleep(50);
string result = deviceInTest.ReadLine();
if (result.StartsWith(correctIdentificationResponse))
{
wantedEquipmentList.Add(aSerialPort);
}
}
return wantedEquipmentList;
}
这里是关于 Bruno Belmonde 解决方案的新实现:
class DeviceIdentifier
{
private List<DeviceFactory> factories = new List<DeviceFactory>();
public void AddDeviceType(DeviceFactory factory) => factories.Add(factory);
public ISerialDevice BuildDeviceByIdentification(String comPort, int baudrate, String identificationCommand, String identificationResponse) => factories.FirstOrDefault(deviceFactory => IdentifyEquipment(comPort, baudrate, identificationCommand, identificationResponse))?.Builder();
private bool IdentifyEquipment(String comPort, int baudrate, String identificationCommand, String identificationResponse)
{
bool foundIt = false;
SerialPort deviceInTest = new SerialPort(comPort, baudrate);
deviceInTest.ReadTimeout = 200;
deviceInTest.Open();
try
{
deviceInTest.WriteLine(identificationCommand);
System.Threading.Thread.Sleep(50);
string result = deviceInTest.ReadLine();
if (result.StartsWith(identificationResponse))
{
foundIt = true;
}
}
catch
{
//........
}
deviceInTest.Close();
return foundIt;
}
}
// MAIN
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
List<EquipmentTypeA> typeAList = new List<EquipmentTypeA>();
deviceIdentifier.AddDeviceType(new DeviceFactory
{
Baudrate = 9600,
IdentificationCommand = "You are ?",
IdentificationResponse = "Type A",
Builder = () => new EquipmentTypeA(9600)
});
foreach(String aSerialPort in SerialPort.GetPortNames())
{
ISerialDevice identifiedObject = deviceIdentifier.BuildDeviceByIdentification(aSerialPort, 9600, "You are ?", "Type A");
if (identifiedObject != null)
typeAList.Add((EquipmentTypeA)identifiedObject);
}
【问题讨论】:
-
首先想到的问题是你打算如何使用它?答案会因用例而异。覆盖静态方法很可能是一个糟糕的选择,因为如果您有任何多态集合(或任何多态声明),它将无法工作
-
您只有几个选项 2,3,4,6,10 用于车轮...只需为它们使用枚举... 耸耸肩
-
@BrunoBelmondo 本例中的wheelNumber 值对应于Serial Equipments(Base class)不同种类(Child class)的默认波特率。我正在使用波特率和许多其他静态属性来首先识别我正在与之交谈的设备,然后我开始使用它。
-
@KevinCook 正如我所说的,这只是一个示例,我的应用程序与车辆无关,因此我的属性可以具有随机值。此外,如果我想在不创建对象的情况下访问子类的特定值,我认为枚举不会改变任何东西,我仍然需要将其作为静态对象。
-
如果“您正在与设备通话”,那么您很可能拥有它的实例。为什么使用静态字段而不是实例字段?这就是我需要用法来回答的地方...
标签: c# .net performance inheritance