I have two methods that basically converts underlying checkboxes' text or tag as CSV strings.
These two methods
differ only by which property to extract value from SelectedCheckBoxes, which is of type IList<CheckBox>
public string GetSelectedTextAsCsv()
{
var buffer = new StringBuilder();
foreach (var cb in SelectedCheckBoxes)
{
buffer.Append(cb.Text).Append(",");
}
return DropLastComma(buffer.ToString());
}
public string GetTagAsCsv()
{
var buffer = new StringBuilder();
foreach (var cb in SelectedCheckBoxes)
{
buffer.Append(cb.Tag).Append(",");
}
return DropLastComma(buffer.ToString());
}
I was trying to extract a method that returns a Func<T, TResult> but not sure how I can pull that off.
My poor attempt was like the following but I cannot figure out how to extract the property portion as shown in the comment within ConvertToCsv()
public Func<T, string> ConvertToCsv<T>()
{
return propertyName =>
{
var buffer = new StringBuilder();
foreach (var checkBox in SelectedCheckBoxes)
{
buffer.Append(
/* How can you abstract this portion? like following? */
checkBox.propertyName
).Append(",");
}
return DropLastComma(buffer.ToString());
};
}
If I am on a wrong track, would you please advise me on how I can refactor above code to use a common method?
[UPDATE 1] Here is the combination of both Brian and Jon's answers
public string ConvertToCsv<T>(Func<CheckBox, T> getValue)
{
var stringValues = SelectedCheckBoxes.Select(
cb => getValue(cb).ToString()).ToArray();
return string.Join(",", stringValues);
}
public string GetSelectedTextAsCsv()
{
return ConvertToCsv(cb => cb.Text);
}
public string GetTagAsCsv()
{
return ConvertToCsv(cb => cb.Tag);
}
[UPDATE 2] version 2
public string GetAsCsv<T>(Func<CheckBox, T> getValue)
{
return string.Join(",", SelectedCheckBoxes.Select(
cb => getValue(cb).ToString()).ToArray());
}
public string GetSelectedTextAsCsv()
{
return GetAsCsv(cb => cb.Text);
}
public string GetTagAsCsv()
{
return GetAsCsv(cb =>
cb.Tag == null ? string.Empty : cb.Tag.ToString());
}
[UPDATE 3] Made the parameter of GetAsCsv() as a closed generic of CheckBox and string
Func<CheckBox, T>toFunc<CheckBox, string>.
That allowed me to make GetAsCsv() even simpler and more readable.
private string GetAsCsv(Func<CheckBox, string> getValue)
{
return string.Join(",", SelectedCheckBoxes.Select(getValue).ToArray());
}
public string GetAsCsv(Func<CheckBox, string> getValue)
{
var buffer = new StringBuilder();
foreach (var cb in SelectedCheckBoxes)
{
buffer.Append(getValue(cb)).Append(",");
}
return DropLastComma(buffer.ToString());
}
Then:
GetAsCsv(cb => cb.Tag != null ? cb.Tag.ToString() : string.Empty);
GetAsCsv(cb => cb.Text);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With