patterncsharpMinor
Writing data to a file
Viewed 0 times
filewritingdata
Problem
I have the following two methods that write to file various data line by line. Both methods differ from each other only by few lines what would be the best way to refactor them that when in future I want to add another method (for example,
```
public string CreateCVTLegacyInFile()
{
try
{
string dllLocation = string.Format("{0}\\{1}\\cvt\\", dllWorkingDirectory, FactoryCode);
string inFile = string.Empty;
inFile += AddLineWithMarks(dllLocation);
inFile += AddLineWithMarks(mainData.CalculationReference);
inFile += AddLineWithMarks(DateTime.Now.ToString("MM/dd/yy").Replace('-', '/'));
inFile += AddLineWithMarks(mainData.Designer);
inFile += AddLineWithMarks(mainData.TransformerType);
inFile += AddLine(mainData.TransformerSize);
inFile += AddLineWithMarks(mainData.TransformerModel);
inFile += AddLineWithMarks(mainData.MainStandard);
inFile += AddLineWithMarks(mainData.SecondaryStandard);
inFile += AddLine(mainData.Frequency);
inFile += AddLine(mainData.HighestSystemVoltage);
inFile += AddLine(mainData.PowerFrequencyInsulationLevel);
inFile += AddLine(mainData.LightningInsulationLevel + "," + mainData.SwitchingInsulationLevel);
inFile += AddLineWithMarks(vtData.RatedVoltage);
inFile += AddLineWithMarks(capacitanceData.NominalIntermediateVoltage);
inFile += AddLine(vtData.VoltageFactor);
inFile += AddLineWithMarks(vtData.VoltageFactorTime);
inFile += AddLine(mainData.MinimumAmbientTemperature + "," + mainData.MaximumAmbientTemperature + "," + mainData.AverageAmbientTemperature);
inFile += AddLineWithMarks(capacitanceData.CVDType);
inFile += AddLineWithMarks(capacitanceData.EMUType);
inFile += AddLine(capacitanceData.EquivalentCapacitance);
inFile += AddLine(capacitanceData.TotalNumberOfElements + "," + capacitanceD
CreateXYZLegacyInFile) it would be least time consuming.```
public string CreateCVTLegacyInFile()
{
try
{
string dllLocation = string.Format("{0}\\{1}\\cvt\\", dllWorkingDirectory, FactoryCode);
string inFile = string.Empty;
inFile += AddLineWithMarks(dllLocation);
inFile += AddLineWithMarks(mainData.CalculationReference);
inFile += AddLineWithMarks(DateTime.Now.ToString("MM/dd/yy").Replace('-', '/'));
inFile += AddLineWithMarks(mainData.Designer);
inFile += AddLineWithMarks(mainData.TransformerType);
inFile += AddLine(mainData.TransformerSize);
inFile += AddLineWithMarks(mainData.TransformerModel);
inFile += AddLineWithMarks(mainData.MainStandard);
inFile += AddLineWithMarks(mainData.SecondaryStandard);
inFile += AddLine(mainData.Frequency);
inFile += AddLine(mainData.HighestSystemVoltage);
inFile += AddLine(mainData.PowerFrequencyInsulationLevel);
inFile += AddLine(mainData.LightningInsulationLevel + "," + mainData.SwitchingInsulationLevel);
inFile += AddLineWithMarks(vtData.RatedVoltage);
inFile += AddLineWithMarks(capacitanceData.NominalIntermediateVoltage);
inFile += AddLine(vtData.VoltageFactor);
inFile += AddLineWithMarks(vtData.VoltageFactorTime);
inFile += AddLine(mainData.MinimumAmbientTemperature + "," + mainData.MaximumAmbientTemperature + "," + mainData.AverageAmbientTemperature);
inFile += AddLineWithMarks(capacitanceData.CVDType);
inFile += AddLineWithMarks(capacitanceData.EMUType);
inFile += AddLine(capacitanceData.EquivalentCapacitance);
inFile += AddLine(capacitanceData.TotalNumberOfElements + "," + capacitanceD
Solution
First, as mentioned in comments above, for efficiency you should be using
The simplest answer I can give is to show you an example of how I might tackle the problem. The following uses a helper class
What follows includes lots of second guesses based on the code snippet provided but hopefully it shows you a way to get started.
Why bother defining this new helper class
The more succinct form below is slightly easier to read and that in itself might be a good enough reason to use a helper...:
... but it also helps to encapsulate all the formatting logic within one place. This might benefit us in future when we need to add newer line categories (by defining new methods), or perhaps define different mark characters to be used (by adding a new class constructor that allows the default characters to be overridden).
Perhaps we will write another version of the
Designing in this way, separating out concerns, is good practice and beneficial to code reuse and mainte
StringBuilder when appending lots of strings repeatedly to make one big string.The simplest answer I can give is to show you an example of how I might tackle the problem. The following uses a helper class
FileContentWithMarks with the "know-how" for your custom formatting, and an instance of StringBuilder to build up the string.What follows includes lots of second guesses based on the code snippet provided but hopefully it shows you a way to get started.
public enum ExportTransformerType
{
Unknown,
NonCapacitive,
Capacitive
}
public string CreateLegacyInFile()
{
try
{
var inFile = new FileContentWithMarks();
// Here, I am assuming this is a way to derive the file type. YMMV.
ExportTransformerType transformerType = DeriveTransformerType(mainData.TransformerType);
inFile.AppendLineWithMarks(GetFolderLocation(transformerType));
// Lines which are common beteween all types can go here verbatim.
// You should also consider whether these can be organised into sub-methods
// for a better overall picture of what's going on.
inFile.AppendLineWithMarks(mainData.CalculationReference);
inFile.AppendLineWithMarks(DateTime.Now.ToString("MM/dd/yy").Replace('-', '/'));
inFile.AppendLineWithMarks(mainData.Designer);
inFile.AppendLineWithMarks(mainData.TransformerType);
inFile.AppendLine(mainData.TransformerSize +
(transformerType == ExportTransformerType.Capacitive ?
string.Empty
:
mainData.TransformerExtension));
inFile.AppendLineWithMarks(mainData.TransformerModel);
inFile.AppendLineWithMarks(mainData.MainStandard);
// ... etc. More shared logic lines copied here
if (transformerType == ExportTransformerType.Capacitive)
{
inFile.AppendLineWithMarks(capacitanceData.NominalIntermediateVoltage);
}
/// ... etc.
inFile.AppendLineWithMarks(gyrStatus);
// Finally, ask the helper to generate the complete string.
return inFile.ToString();
}
catch (Exception ex)
{
throw ex;
}
}
public ExportTransformerType DeriveTransformerType(string typeName)
{
if (typeName == "CVT")
return ExportTransformerType.Capacitive;
if (typeName == "VT")
return ExportTransformerType.NonCapacitive;
return ExportTransformerType.Unknown;
}
public string GetFolderLocation(ExportTransformerType transformerType)
{
string subFolder;
switch (transformerType)
{
case ExportTransformerType.NonCapacitive:
subFolder = "vt";
break;
case ExportTransformerType.Capacitive:
subFolder = "cvt";
break;
default:
subFolder = "unknown"; // or raise an exception if you prefer
break;
}
return string.Format("{0}\\{1}\\{2}\\", dllWorkingDirectory, FactoryCode, subFolder);
}
// Wrapper for StringBuilder with specific line formatting/markings
public class FileContentWithMarks
{
private StringBuilder _content = new StringBuilder();
public void AppendLine(string line)
{
// The logic for how you format lines without marks can go here
_content.AppendLine(line);
}
public void AppendLineWithMarks(string line)
{
// The logic for how you format lines with marks can go here
_content.AppendLine("{" + line + "}");
}
public override string ToString()
{
return _content.ToString();
}
}Why bother defining this new helper class
FileContentWithMarks? Let's look at the style of code required if inFile was a pure StringBuilder:inFile.Append(AddLineWithMarks(mainData.Designer));
inFile.Append(AddLineWithMarks(mainData.TransformerType));The more succinct form below is slightly easier to read and that in itself might be a good enough reason to use a helper...:
inFile.AppendLineWithMarks(mainData.Designer);
inFile.AppendLineWithMarks(mainData.TransformerType);... but it also helps to encapsulate all the formatting logic within one place. This might benefit us in future when we need to add newer line categories (by defining new methods), or perhaps define different mark characters to be used (by adding a new class constructor that allows the default characters to be overridden).
Perhaps we will write another version of the
FileContentWithMarks class, make both of them implement the same interface, but this version streams the lines both to a console and to a log file at once, doing away with the StringBuilder altogether. Then we can choose at runtime which class to instantiate without needing to change any of the instance method calls.Designing in this way, separating out concerns, is good practice and beneficial to code reuse and mainte
Code Snippets
public enum ExportTransformerType
{
Unknown,
NonCapacitive,
Capacitive
}
public string CreateLegacyInFile()
{
try
{
var inFile = new FileContentWithMarks();
// Here, I am assuming this is a way to derive the file type. YMMV.
ExportTransformerType transformerType = DeriveTransformerType(mainData.TransformerType);
inFile.AppendLineWithMarks(GetFolderLocation(transformerType));
// Lines which are common beteween all types can go here verbatim.
// You should also consider whether these can be organised into sub-methods
// for a better overall picture of what's going on.
inFile.AppendLineWithMarks(mainData.CalculationReference);
inFile.AppendLineWithMarks(DateTime.Now.ToString("MM/dd/yy").Replace('-', '/'));
inFile.AppendLineWithMarks(mainData.Designer);
inFile.AppendLineWithMarks(mainData.TransformerType);
inFile.AppendLine(mainData.TransformerSize +
(transformerType == ExportTransformerType.Capacitive ?
string.Empty
:
mainData.TransformerExtension));
inFile.AppendLineWithMarks(mainData.TransformerModel);
inFile.AppendLineWithMarks(mainData.MainStandard);
// ... etc. More shared logic lines copied here
if (transformerType == ExportTransformerType.Capacitive)
{
inFile.AppendLineWithMarks(capacitanceData.NominalIntermediateVoltage);
}
/// ... etc.
inFile.AppendLineWithMarks(gyrStatus);
// Finally, ask the helper to generate the complete string.
return inFile.ToString();
}
catch (Exception ex)
{
throw ex;
}
}
public ExportTransformerType DeriveTransformerType(string typeName)
{
if (typeName == "CVT")
return ExportTransformerType.Capacitive;
if (typeName == "VT")
return ExportTransformerType.NonCapacitive;
return ExportTransformerType.Unknown;
}
public string GetFolderLocation(ExportTransformerType transformerType)
{
string subFolder;
switch (transformerType)
{
case ExportTransformerType.NonCapacitive:
subFolder = "vt";
break;
case ExportTransformerType.Capacitive:
subFolder = "cvt";
break;
default:
subFolder = "unknown"; // or raise an exception if you prefer
break;
}
return string.Format("{0}\\{1}\\{2}\\", dllWorkingDirectory, FactoryCode, subFolder);
}
// Wrapper for StringBuilder with specific line formatting/markings
public class FileContentWithMarks
{
private StringBuilder _content = new StringBuilder();
public void AppendLine(string line)
{
// The logic for how you format lines without marks can go here
_content.AppendLine(line);
}
public void AppendLineWithMarks(string line)
{
// The logic for how you format lines with marks can go here
_conteinFile.Append(AddLineWithMarks(mainData.Designer));
inFile.Append(AddLineWithMarks(mainData.TransformerType));inFile.AppendLineWithMarks(mainData.Designer);
inFile.AppendLineWithMarks(mainData.TransformerType);Context
StackExchange Code Review Q#117620, answer score: 2
Revisions (0)
No revisions yet.