Mam dwie metody, które zasadniczo konwertuje tekst lub znacznik pola wyboru jako ciągi CSV.
Czy można refactor out wspólnej funkcji z tych dwóch metod?
Te dwie metody
- GetSelectedTextAsCsv()
- GetTagAsCsv()
różnią się tylko w którym właściwość wyodrębnić wartość od SelectedCheckBoxes
, który jest typu 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());
}
Próbowałem wyodrębnić metodę, która zwraca Func<T, TResult>
, ale nie jestem pewien, jak mogę to zrobić. Mój biedny próba była jak poniżej, ale nie mogę dowiedzieć się, jak wyodrębnić część nieruchomości, jak pokazano w komentarzu ciągu 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());
};
}
Jeśli jestem na złej drodze, to proszę mi doradzić, w jaki sposób mogę refactor powyżej kodu, aby użyć wspólnej metody?
[UPDATE 1] Oto połączenie obu Brian i odpowiedzi Jona
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] wersja 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 parametr GetAsCsv()
jako zamknięty generic CheckBox i ciąg
Func<CheckBox, T>
doFunc<CheckBox, string>
.
To pozwoliło mi uczynić GetAsCsv()
jeszcze prostszym i bardziej czytelnym.
private string GetAsCsv(Func<CheckBox, string> getValue)
{
return string.Join(",", SelectedCheckBoxes.Select(getValue).ToArray());
}
Używam twojego rozwiązania, a także Jona. Trudno zdecydować ... – Sung
w00t! Programowanie funkcjonalne :) – Juliet
@Princess: Czy jest to podejście do programowania funkcjonalnego? Nie mam pojęcia o tym ... – Sung