避免代码重复 c#
Avoid code repeating c#
目前正在为万用表制作库,此时我发现自己在重复自己。我在问,如何连接这两个功能。这只是开始,我将有更多类似的功能,我只需要某种示例,或修复此特定代码,然后我就能自己弄清楚其他人。
public string MeasureVoltage()
{
string Meas = "MEAS:VOLT:";
if (vt == VoltageType.DC)
{
Meas += "DC?";
}
else
{
Meas += "AC?";
}
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
public string MeasureCurrent()
{
string Meas = "MEAS:CURR:";
if (ct == CurrentType.DC)
{
Meas += "DC?";
}
else
{
Meas += "AC?";
}
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
public enum VoltageType { AC, DC }
public enum CurrentType { AC, DC }
我猜你可以制作一个 Measure 方法,并给出一个你想要它测量的参数,然后只对你当前方法之间不同的东西使用 switch 语句
我会放
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
在它自己的方法中并从两者调用它:
public string MeasureVoltage()
{
string Meas = "MEAS:VOLT:";
if (vt == VoltageType.DC)
{
Meas += "DC?";
}
else
{
Meas += "AC?";
}
return PerformMeasurement(Meas);
}
public string MeasureCurrent()
{
string Meas = "MEAS:CURR:";
if (ct == CurrentType.DC)
{
Meas += "DC?";
}
else
{
Meas += "AC?";
}
return PerformMeasurement(Meas);
}
private string PerformMeasurement(string Meas)
{
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
如果您希望 MeasureVoltage
/MeasureCurrent
显得更短,请内联创建 Meas
:
public string MeasureVoltage() => PerformMeasurement( $"MEAS:VOLT:{vt}?" );
编辑:如果您可以选择 enum
值名称来匹配所需的字符串,则可以完全删除 if
。
只需将第一行替换为:
public string MeasureVoltage()
{
string Meas = "MEAS:VOLT:" + (vt == VoltageType.DC ? "DC?" : "AC?");
return Measure(meas);
}
public string MeasureCurrent()
{
string Meas = "MEAS:CURR:" + (ct == CurrentType.DC ? "DC?" : "AC?");
return Measure(meas);
}
现在将两种方法之间的共同点提取到此:
private string Measure(string measure)
{
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
一个更好的方法是拥有两个独立的值,一个存储度量的类型(volt
或 current
),另一个存储度量的类型(DC
或 AC
):
class MyType
{
private string Type; // either CURR or VOLT
private string otherType; // either DC or AC
public MyType(string type, otherType)
{ /* fill the members */ }
}
现在你甚至不需要两种方法,只需要这个:
public string Measure()
{
var measure = "MEAS:" + this.Type + ":" + this.OtherType + "?\n";
io.PrintfAndFlush(measure );
Console.WriteLine(measure );
string response;
io.Scanf("%s", out response);
return response;
}
现在简单地调用这个:
var m = new MyType("VOLT", "AC");
var result = m.Measure();
将打印 "MEAS:VOLT:AC?"
.
我认为这是我使用您提供的代码所能做的最好的事情:
public enum VoltageType { AC, DC}
public enum CurrentType { AC, DC}
public string MeasureVoltage()
{
return Measure(MeasureType.Voltage);
}
public string MeasureCurrent()
{
return Measure(MeasureType.Current);
}
private enum MeasureType {Voltage, Current}
private string Measure(MeasureType mt)
{
var what = (mt == Voltage) ? "VOLT" : "CURR";
var type = ((mt == MeasureType.Voltage && vt == VoltageType.AC) ||
(mt == MeasureType.Current && ct == CurrentType.AC)) ? "AC" : "DC";
// c# 6 or higher:
var Meas = $"MEAS:{what}:{type}?";
// for older versions of c#, use string.Format:
// var Meas = string.Format("MEAS:{0}:{1}?", what, type);
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
public string MeasureVoltage()
{
return DoMeasurement($"MEAS:VOLT:{vt.ToString()}?");
}
public string MeasureCurrent()
{
return DoMeasurement($"MEAS:CURR:{ct.ToString()}?");
}
private string DoMeasurement(string Meas)
{
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
public enum VoltageType { AC, DC }
public enum CurrentType { AC, DC }
很简单,是吧? :)
$""
语法就是所谓的 interpolated string,它在 C# 6.0 中可用。如果您使用的是早期版本,可以将其替换为 string.Format()
,如下所示:
DoMeasurement(stringFormat("MEAS:VOLT:{0}?", vt.ToString()));
在这些情况下,您应该问自己的第一个问题是 "is it really the same?"。
如果是,那么你是对的,它可能是重复的,可能应该避免。请注意,我说过 "probably" - 这不是硬性规定,有时重复可能是必要的,甚至是好的,例如如果它增加了清晰度。
如果不是,那么避免看似重复的代码实际上可能是一件坏事。它不仅会使您的代码更加混乱,而且可能会完全忽略要点 - 例如如果你有一个狗对象和一个 table 对象,并决定因为它们都有 4 条腿,所以它们是一样的东西,你可能会遇到试图把咖啡放在 Spot 上的人——我很确定他反对!注意对相同方法的一些调用,特别是如果它们是像 WriteLine
这样的实用方法,则不算作重复。
在你的情况下,我认为你的行为有两个方面 - 确定要进行的测量,然后进行测量。
查看您的代码,您的 "taking the measurement" 东西是相同的;一个好的第一步可能是将它拉出到一个 "Measure" 方法中,像这样
public string MeasureVoltage()
{
string Meas = "MEAS:VOLT:";
if (vt == VoltageType.DC)
{
Meas += "DC?";
}
else
{
Meas += "AC?";
}
return Measure(Meas);
}
public string MeasureCurrent()
{
string Meas = "MEAS:CURR:";
if (ct == CurrentType.DC)
{
Meas += "DC?";
}
else
{
Meas += "AC?";
}
return Measure(Meas);
}
public string Measure(string Meas)
{
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
请注意,我保留了您的代码格式,以说明它是一个简单的“将 Measure
中的所有内容复制到一个单独的方法中,并将其替换为对 Measure(Meas)
.
的调用
更进一步;您的 Voltage 和 Current 枚举是相同的 - 从代码的角度来看,这没有什么意义,而且无论如何,这不像您获得 AC 电压和 DC 电流。考虑到这一点,您可以删除重复项 - 让我们调用替换 "PowerType" ,因为它涵盖了两者。此外,您可以决定此电源类型和测量类型都是您的测量方法的参数,并执行类似这样的操作
public enum PowerType { AC, DC }
public string Measure(string measurementType, PowerType pt)
{
string powerString = pt == PowerType.AC ? "AC" : "DC";
string measurement = measurementType + powerString;
io.PrintfAndFlush(measurement + "\n");
Console.WriteLine(measurement);
string response;
io.Scanf("%s", out response);
return response;
}
目前正在为万用表制作库,此时我发现自己在重复自己。我在问,如何连接这两个功能。这只是开始,我将有更多类似的功能,我只需要某种示例,或修复此特定代码,然后我就能自己弄清楚其他人。
public string MeasureVoltage()
{
string Meas = "MEAS:VOLT:";
if (vt == VoltageType.DC)
{
Meas += "DC?";
}
else
{
Meas += "AC?";
}
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
public string MeasureCurrent()
{
string Meas = "MEAS:CURR:";
if (ct == CurrentType.DC)
{
Meas += "DC?";
}
else
{
Meas += "AC?";
}
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
public enum VoltageType { AC, DC }
public enum CurrentType { AC, DC }
我猜你可以制作一个 Measure 方法,并给出一个你想要它测量的参数,然后只对你当前方法之间不同的东西使用 switch 语句
我会放
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
在它自己的方法中并从两者调用它:
public string MeasureVoltage()
{
string Meas = "MEAS:VOLT:";
if (vt == VoltageType.DC)
{
Meas += "DC?";
}
else
{
Meas += "AC?";
}
return PerformMeasurement(Meas);
}
public string MeasureCurrent()
{
string Meas = "MEAS:CURR:";
if (ct == CurrentType.DC)
{
Meas += "DC?";
}
else
{
Meas += "AC?";
}
return PerformMeasurement(Meas);
}
private string PerformMeasurement(string Meas)
{
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
如果您希望 MeasureVoltage
/MeasureCurrent
显得更短,请内联创建 Meas
:
public string MeasureVoltage() => PerformMeasurement( $"MEAS:VOLT:{vt}?" );
编辑:如果您可以选择 enum
值名称来匹配所需的字符串,则可以完全删除 if
。
只需将第一行替换为:
public string MeasureVoltage()
{
string Meas = "MEAS:VOLT:" + (vt == VoltageType.DC ? "DC?" : "AC?");
return Measure(meas);
}
public string MeasureCurrent()
{
string Meas = "MEAS:CURR:" + (ct == CurrentType.DC ? "DC?" : "AC?");
return Measure(meas);
}
现在将两种方法之间的共同点提取到此:
private string Measure(string measure)
{
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
一个更好的方法是拥有两个独立的值,一个存储度量的类型(volt
或 current
),另一个存储度量的类型(DC
或 AC
):
class MyType
{
private string Type; // either CURR or VOLT
private string otherType; // either DC or AC
public MyType(string type, otherType)
{ /* fill the members */ }
}
现在你甚至不需要两种方法,只需要这个:
public string Measure()
{
var measure = "MEAS:" + this.Type + ":" + this.OtherType + "?\n";
io.PrintfAndFlush(measure );
Console.WriteLine(measure );
string response;
io.Scanf("%s", out response);
return response;
}
现在简单地调用这个:
var m = new MyType("VOLT", "AC");
var result = m.Measure();
将打印 "MEAS:VOLT:AC?"
.
我认为这是我使用您提供的代码所能做的最好的事情:
public enum VoltageType { AC, DC}
public enum CurrentType { AC, DC}
public string MeasureVoltage()
{
return Measure(MeasureType.Voltage);
}
public string MeasureCurrent()
{
return Measure(MeasureType.Current);
}
private enum MeasureType {Voltage, Current}
private string Measure(MeasureType mt)
{
var what = (mt == Voltage) ? "VOLT" : "CURR";
var type = ((mt == MeasureType.Voltage && vt == VoltageType.AC) ||
(mt == MeasureType.Current && ct == CurrentType.AC)) ? "AC" : "DC";
// c# 6 or higher:
var Meas = $"MEAS:{what}:{type}?";
// for older versions of c#, use string.Format:
// var Meas = string.Format("MEAS:{0}:{1}?", what, type);
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
public string MeasureVoltage()
{
return DoMeasurement($"MEAS:VOLT:{vt.ToString()}?");
}
public string MeasureCurrent()
{
return DoMeasurement($"MEAS:CURR:{ct.ToString()}?");
}
private string DoMeasurement(string Meas)
{
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
public enum VoltageType { AC, DC }
public enum CurrentType { AC, DC }
很简单,是吧? :)
$""
语法就是所谓的 interpolated string,它在 C# 6.0 中可用。如果您使用的是早期版本,可以将其替换为 string.Format()
,如下所示:
DoMeasurement(stringFormat("MEAS:VOLT:{0}?", vt.ToString()));
在这些情况下,您应该问自己的第一个问题是 "is it really the same?"。
如果是,那么你是对的,它可能是重复的,可能应该避免。请注意,我说过 "probably" - 这不是硬性规定,有时重复可能是必要的,甚至是好的,例如如果它增加了清晰度。
如果不是,那么避免看似重复的代码实际上可能是一件坏事。它不仅会使您的代码更加混乱,而且可能会完全忽略要点 - 例如如果你有一个狗对象和一个 table 对象,并决定因为它们都有 4 条腿,所以它们是一样的东西,你可能会遇到试图把咖啡放在 Spot 上的人——我很确定他反对!注意对相同方法的一些调用,特别是如果它们是像 WriteLine
这样的实用方法,则不算作重复。
在你的情况下,我认为你的行为有两个方面 - 确定要进行的测量,然后进行测量。
查看您的代码,您的 "taking the measurement" 东西是相同的;一个好的第一步可能是将它拉出到一个 "Measure" 方法中,像这样
public string MeasureVoltage()
{
string Meas = "MEAS:VOLT:";
if (vt == VoltageType.DC)
{
Meas += "DC?";
}
else
{
Meas += "AC?";
}
return Measure(Meas);
}
public string MeasureCurrent()
{
string Meas = "MEAS:CURR:";
if (ct == CurrentType.DC)
{
Meas += "DC?";
}
else
{
Meas += "AC?";
}
return Measure(Meas);
}
public string Measure(string Meas)
{
io.PrintfAndFlush(Meas + "\n");
Console.WriteLine(Meas);
string response;
io.Scanf("%s", out response);
return response;
}
请注意,我保留了您的代码格式,以说明它是一个简单的“将 Measure
中的所有内容复制到一个单独的方法中,并将其替换为对 Measure(Meas)
.
更进一步;您的 Voltage 和 Current 枚举是相同的 - 从代码的角度来看,这没有什么意义,而且无论如何,这不像您获得 AC 电压和 DC 电流。考虑到这一点,您可以删除重复项 - 让我们调用替换 "PowerType" ,因为它涵盖了两者。此外,您可以决定此电源类型和测量类型都是您的测量方法的参数,并执行类似这样的操作
public enum PowerType { AC, DC }
public string Measure(string measurementType, PowerType pt)
{
string powerString = pt == PowerType.AC ? "AC" : "DC";
string measurement = measurementType + powerString;
io.PrintfAndFlush(measurement + "\n");
Console.WriteLine(measurement);
string response;
io.Scanf("%s", out response);
return response;
}