我有一种感觉我做错了。我是抽象类等的新手,并且已经阅读了一些教程,但我无法弄清楚如何将它应用到我的情况中。我认为我的设计可能有问题,但我想不出另一种方法。我公司制造了几台不同的电脑,我需要能够监控电池信息。虽然获取信息不是问题,但要弄清楚如何将不同的命令发送到基类来完成我需要它做的事情。说我想让我的电池1电压。在一个单元上,命令是0x0418,在另一个单元上,它是0x453。所以在我的信息类中,我运行测试以查看模型是什么。我有一个叫做电池的Base类,它有一堆变量,是每个电池的标准电池(电池电压,充电电流,充电电流等等)然后我决定为每个扩展电池的单元制作单独的类。
现在我认为我所设计的类是可靠的(可能是错误的,因为我不擅长抽象和多态)。我有一个面板,最后会显示我从BatteryInformation类获得的信息。像Battery1Cell1Label.Text = batteryInfo.GetCell1(1); Battery2Cell1Label = batteryInfo.GetCell1(2)。
所以在我的基类中我想我需要一个GetValue(字节命令)(因为它是一个嵌入式控制器命令来获取每种不同类型的信息。)也许我应该停止说话,只是发布我的代码我拥有的和告诉你我的错误。
battery.cs
public abstract class Battery<T> //not sure that the <T> is right
{
public string Information { get; private set; }
public float Cell1 { get; private set; }
public float Cell2 { get; private set; }
public float Cell3 { get; private set; }
public float Cell4 { get; private set; }
public int FCC { get; private set; }
public bool ChargeIC { get; private set; }
public int StartCharge { get; private set; }
public int CurrentCharge { get; private set; }
public bool Exists { get; private set; }
protected internal void GetValue(byte command)
{
//Use Embedded controller to get said value
//ECPort.ReadEC(command);
//Testing Purposeses
Console.WriteLine(command);
}
}
Battery8800.cs
class Battery8800 : Battery<Battery8800>
{
public Battery8800() : base()
{
}
public void GetValue(BatteryCommands command)
{
base.GetValue((byte)command);
}
public enum BatteryCommands
{
Battery1VoltageHigh = 0x0402,
Battery1VoltageLow = 0x0403,
Batt1ChargeCurrentHigh = 0x0404,
Batt1ChargeCurrentLow = 0x0405,
Battery1MaxError = 0x0407,
Battery1RSOC = 0x0409,
Battery1FCCHigh = 0x040E,
Battery1FCCLow = 0x040F,
Battery1DCHigh = 0x0412,
Battery1DCLow = 0x0413,
Battery1Cell1High = 0x0418,
Battery1Cell1Low = 0x0419,
Battery1Cell2High = 0x041A,
Battery1Cell2Low = 0x041B,
Battery1Cell3High = 0x041C,
Battery1Cell3Low = 0x041D,
Battery1Cell4High = 0x041E,
Battery1Cell4Low = 0x041F,
PowerSource1 = 0x0420,
//many more commands for battery 2 etc etc
}
}
BatteryInformation.cs
class BatteryInformation
{
public Battery battery1; //error says it needs 1 type of argument
public Battery battery2; //error says it needs 1 type of argument
public BatteryInformation()
{
switch (UnitModel.GetModelEnum())
{
case UnitModel.DLIModel.DLI8300M:
battery1 = new Battery8300();
battery2 = new Battery8300();
break;
case UnitModel.DLIModel.DLI8400:
battery1 = new Battery8400();
battery2 = new Battery8400();
break;
case UnitModel.DLIModel.DLI8500:
battery1 = new Battery8500();
break;
case UnitModel.DLIModel.DLI8500P:
battery1 = new Battery8500P();
break;
case UnitModel.DLIModel.DLI8800:
battery1 = new Battery8800();
break;
case UnitModel.DLIModel.DLI9200:
battery1 = new Battery9200();
break;
default:
break;
}
//for testing purposes
battery1 = new Battery8800();
battery1.DoThis(Battery8800.BatteryCommands.Batt1ChargeCurrentHigh);
}
}
YEAH拯救草案!!!权力刚刚消失,我没有松开,只有一句话!
所以当我的电脑重新开启时,我觉得在我的电池组课上做这样的事可能会更好。
//in my timer_tick event
BatteryInformation.UpdateBatteries();
battery1Cell1Label.Text = BatteryInformation.Battery1.Cell1.ToString();
//etc etc
但我仍然需要让这个工作,但我很难搞清楚如何进行抽象。谢谢你的时间。
修改
我想我会以错误的方式解决这个问题。
class Battery1_8400 : Battery
{
public override bool Update()
{
//TODO finish
Exists = GetValue((ushort)Commands.PowerSource) != 0xFF;
if (Exists)
{
Cell1 = GetValue((ushort)Commands.Cell1Low, (ushort)Commands.Cell1High) / 1000.0f;
Cell2 = GetValue((ushort)Commands.Cell2Low, (ushort)Commands.Cell2High) / 1000.0f;
Cell3 = GetValue((ushort)Commands.Cell3Low, (ushort)Commands.Cell3High) / 1000.0f;
FCC = GetValue((ushort)Commands.FCCLow, (ushort)Commands.FCCHigh);
Voltage = GetValue((ushort)Commands.VoltageLow, (ushort)Commands.VoltageHigh);
return true;
}
else
{
return false;
}
}
private enum Commands
{
PowerSource = 0x0480,
Charge = 0x0432,
RSOC = 0x0734,
DCLow = 0x0402,
DCHigh = 0x0403,
FCCLow = 0x0404,
FCCHigh = 0x0405,
MaxError = 0x0730,
Cell1Low = 0x0778,
Cell1High = 0x0779,
Cell2Low = 0x077C,
Cell2High = 0x077D,
Cell3Low = 0x0780,
Cell3High = 0x0781,
VoltageLow = 0x0438,
VoltageHigh = 0x0439,
ChargeCurrentLow = 0x0728,
ChargeCurrentHigh = 0x0729,
ChargeIC = 0x1A03,
}
}
我有9个文件在Update命令的工作方式上完全相同,差异在枚举中。每个类的命令略有不同。看看batter2_8400.cs的枚举
private enum Commands
{
PowerSource = 0x0480,
Charge = 0x04C2,
RSOC = 0x0834,
DCLow = 0x0492,
DCHigh = 0x0493,
FCCLow = 0x0494,
FCCHigh = 0x0495,
MaxError = 0x0830,
Cell1Low = 0x0878,
Cell1High = 0x0879,
Cell2Low = 0x087C,
Cell2High = 0x087D,
Cell3Low = 0x0880,
Cell3High = 0x0881,
VoltageLow = 0x04C8,
VoltageHigh = 0x04C9,
ChargeCurrentLow = 0x0828,
ChargeCurrentHigh = 0x0829,
ChargeIC = 0x1A04,
}
更新命令与该文件中的一个以及其他7个文件完全相同。对我来说似乎有点糟糕的设计,但我很难过如何做到这一点。顺便说一句,这是我给出的一个答案之后我的课程的样子以及收到的一些评论。
答案 0 :(得分:0)
您的基类BatteryInformation应该为您需要检索的每个值提供抽象属性,如下所示:
public abstract class BatteryInfo {
// int should be replaced with the actual data type of the value
public abstract int VoltageHigh { get; }
public abstract int VoltageLow { get; }
// etc. for each value you need
}
然后在您的子类中实现每个属性
public class Battery8800 : BatteryInfo {
public override int VoltageHigh {
get {
int value;
// do code to retrieve value
return value;
}
}
}
另外,我会提供一个UI可以使用的方法,如下所示:
public IEnumerable<BatteryInfo> GetAllBatteryInfo() {
// get each battery
}
这样,用户界面无需担心如何为每个电池检索电池信息。这允许您使用列表或网格样式控件之一来查看电池信息。
答案 1 :(得分:0)
最后我想我想出了我该做什么。它看起来很干净,似乎有道理。也许你可以批评它?
public abstract class Battery
{
public string Information { get; set; }
public float Cell1 { get {return GetValue(Cell1Low, Cell1High) / 1000.0f;} }
public float Cell2 { get {return GetValue(Cell2Low, Cell2High) / 1000.0f;} }
public float Cell3 { get {return GetValue(Cell3Low, Cell3High) / 1000.0f;} }
public float Cell4 { get {return GetValue(Cell4Low, Cell4High) / 1000.0f;} }
public float Voltage { get {return GetValue(VoltageLow, VoltageHigh);} }
public int DC { get {return GetValue(DCLow, DCHigh);} }
public int FCC { get {return GetValue(FCCLow, FCCHigh);} }
//public bool ChargeIC { get {return } }
//public int StartCharge { get {return } }
//public int CurrentCharge { get {return } }
public bool Exists { get {return GetValue(PowerSource) != 0xFF} }
public int FCCPercent { get {return ((FCC * 100) / DC);} }
/// <summary>
/// Gets a value depending on the Embedded controller
/// </summary>
/// <param name="low">The low byte command to process</param>
/// <param name="high">The high byte command to process</param>
/// <returns></returns>
private int GetValue(ushort low, ushort high)
{
//Use Embedded controller to get said value
//ECPort.ReadEC(command);
//Testing Purposeses
var lowValue = ECPort.ReadEC(low);
var highValue = ECPort.ReadEC(high);
return (int)((highValue << 8) + lowValue);
}
private int GetValue(ushort command)
{
return (int)ECPort.ReadEC(command);
}
public abstract ushort PowerSource {get;}
public abstract ushort Charge{get;}
public abstract ushort RSOC{get;}
public abstract ushort DCLow{get;}
public abstract ushort DCHigh{get;}
public abstract ushort FCCLow{get;}
public abstract ushort FCCHigh{get;}
public abstract ushort MaxError{get;}
public abstract ushort Cell1Low{get;}
public abstract ushort Cell1High{get;}
public abstract ushort Cell2Low{get;}
public abstract ushort Cell2High{get;}
public abstract ushort Cell3Low{get;}
public abstract ushort Cell3High{get;}
public abstract ushort Cell4Low { get; }
public abstract ushort Cell4High { get; }
public abstract ushort VoltageLow{get;}
public abstract ushort VoltageHigh{get;}
public abstract ushort ChargeCurrentLow{get;}
public abstract ushort ChargeCurrentHigh{get;}
public abstract ushort ChargeIC{get;}
}
然后在继承它的子类上就是这个
class Battery1_8400 : Battery
{
public override ushort PowerSource { get {return 0x0480;}}
public override ushort Charge { get {return 0x0432;}}
public override ushort RSOC { get {return 0x0734;}}
public override ushort DCLow { get {return 0x0402;}}
public override ushort DCHigh { get {return 0x0403;}}
public override ushort FCCLow { get {return 0x0404;}}
public override ushort FCCHigh { get {return 0x0405;}}
public override ushort MaxError { get {return 0x0730;}}
public override ushort Cell1Low { get {return 0x0778;}}
public override ushort Cell1High { get {return 0x0779;}}
public override ushort Cell2Low { get {return 0x077C;}}
public override ushort Cell2High { get {return 0x077D;}}
public override ushort Cell3Low { get {return 0x0780;}}
public override ushort Cell3High { get {return 0x0781;}}
public override ushort VoltageLow { get {return 0x0438;}}
public override ushort VoltageHigh { get {return 0x0439;}}
public override ushort ChargeCurrentLow { get {return 0x0728;}}
public override ushort ChargeCurrentHigh { get {return 0x0729;}}
public override ushort ChargeIC { get {return 0x1A03;}}
}
现在我所要做的就是编辑一个文件battery.cs,如果我需要对其进行更改。