你能从这两种方法中重构出一个共同的功能吗?

dan*_*die 7 .net c# csv refactoring

我有两种方法基本上将底层复选框的文本或标记转换为CSV字符串.

这两种方法

  • GetSelectedTextAsCsv()
  • GetTagAsCsv()

不同之处仅在于提取值的属性SelectedCheckBoxes,即类型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());
    }
Run Code Online (Sandbox Code Playgroud)

我试图提取一种方法,该方法返回Func<T, TResult>但不确定如何将其拉出来.我的糟糕尝试就像下面这样,但我无法弄清楚如何提取属性部分,如注释中所示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());
        };
    }
Run Code Online (Sandbox Code Playgroud)

如果我走错了路,你能告诉我如何重构代码以使用常用方法吗?

[更新1]这是Brian和Jon的答案的组合

    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);
    }
Run Code Online (Sandbox Code Playgroud)

[更新2]版本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());
    }
Run Code Online (Sandbox Code Playgroud)

[更新3]将参数GetAsCsv()作为CheckBox和字符串的封闭通用

Func<CheckBox, T>Func<CheckBox, string>.

这让我变得GetAsCsv()更简单,更具可读性.

private string GetAsCsv(Func<CheckBox, string> getValue)
{
    return string.Join(",", SelectedCheckBoxes.Select(getValue).ToArray());
}
Run Code Online (Sandbox Code Playgroud)

Bri*_*sio 22

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());
}
Run Code Online (Sandbox Code Playgroud)

然后:

GetAsCsv(cb => cb.Tag != null ? cb.Tag.ToString() : string.Empty);
GetAsCsv(cb => cb.Text);
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 19

我会string.Join改用:

string tags = string.Join(",", 
                  SelectedCheckBoxes.Select(cb => Convert.ToString(cb.Tag))
                                    .ToArray());
string text = string.Join(",", 
                  SelectedCheckBoxes.Select(cb => cb.Text).ToArray());
Run Code Online (Sandbox Code Playgroud)

当然,你可以把它放到一个方法中,但我可能不会只打扰两个电话.

如果你想,这是使用Brian的模板看起来如何:

public string GetAsCsv(Func<CheckBox, string> getValue)
{
    string[] array = SelectedCheckBoxes.Select(getValue).ToArray();
    return string.Join(",", array);
}
Run Code Online (Sandbox Code Playgroud)