Tengo dos métodos que básicamente convierten el texto o la etiqueta de las casillas de verificación subyacentes como cadenas de CSV.
¿Puede refactorizar una funcionalidad común de estos dos métodos?
Estos dos métodos
- GetSelectedTextAsCsv()
- GetTagAsCsv()
difieren sólo por el cual propiedad para extraer valor de SelectedCheckBoxes
, que es de tipo 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());
}
Estaba intentando extraer un método que arroja un Func<T, TResult>
pero no estoy seguro de cómo puedo lograrlo. Mi pobre intento era como el siguiente, pero no puedo encontrar la manera de extraer la parte de la propiedad, como se muestra en el comentario dentro 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());
};
}
Si estoy en un camino equivocado, ¿podría aconsejarme sobre cómo puedo refactorizar el código para usar un método común?
[ACTUALIZACIÓN 1] Aquí es la combinación de ambas respuestas de Jon Brian y
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);
}
[ACTUALIZACIÓN 2] versión 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());
}
[Actualización 3] hizo el parámetro de GetAsCsv()
como un genérico cerrado de CheckBox y cadena
Func<CheckBox, T>
aFunc<CheckBox, string>
.
Eso me permitió hacer GetAsCsv()
aún más simple y más legible.
private string GetAsCsv(Func<CheckBox, string> getValue)
{
return string.Join(",", SelectedCheckBoxes.Select(getValue).ToArray());
}
De hecho estoy utilizando su solución al igual que la de Jon. Es difícil decidir ... – Sung
w00t! Programación funcional :) – Juliet
@Princess: ¿Es un enfoque de programación funcional? Ni siquiera estoy al tanto ... – Sung