代码之家  ›  专栏  ›  技术社区  ›  dance2die

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

  •  7
  • dance2die  · 技术社区  · 16 年前

    我有两种方法,基本上可以将底层复选框的文本或标记转换为csv字符串。

    这两种方法

    • 获取选定的文本ascsv()
    • GETTAGASSV()

    只有在哪方面不同 财产 从中提取值 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());
        }
    

    我试图提取一个返回 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());
            };
        }
    

    如果我走错了轨道,您能告诉我如何重构上面的代码以使用公共方法吗?

    [更新1 ] 这是布莱恩和乔恩的答案的组合

        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);
        }
    

    [更新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());
        }
    

    [更新3 ] 使参数 GetAsCsv() 作为复选框和字符串的封闭泛型

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

    这让我 GETASSV() 更简单,更易读。

    private string GetAsCsv(Func<CheckBox, string> getValue)
    {
        return string.Join(",", SelectedCheckBoxes.Select(getValue).ToArray());
    }
    
    5 回复  |  直到 16 年前
        1
  •  22
  •   Brian Genisio    16 年前
    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());
    }
    

    然后:

    GetAsCsv(cb => cb.Tag != null ? cb.Tag.ToString() : string.Empty);
    GetAsCsv(cb => cb.Text);
    
        2
  •  19
  •   Jon Skeet    16 年前

    我会用 string.Join 而是:

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

    当然,您可以将其放入一个方法中,但我可能不会只为两个调用而烦恼。

    如果你想,下面是使用Brian的模板时的样子:

    public string GetAsCsv(Func<CheckBox, string> getValue)
    {
        string[] array = SelectedCheckBoxes.Select(getValue).ToArray();
        return string.Join(",", array);
    }
    
        3
  •  2
  •   Gabe Moothart    16 年前

    您可以使用lambda:

    public string ConvertToCSV(Func<CheckBox, string> cb_prop) {
        ...
        buffer.Append(cb_prop(cb)).Append(",");
        ...
    
    }
    
    ConvertToCSV(c => c.Tag);
    
        4
  •  1
  •   meandmycode    16 年前

    我只需要在带分隔符的IEnumerable字符串周围编写一个简短的扩展方法:

    public static string Join(this IEnumerable<string> strings, string separator)
    {
        return string.Join(separator, strings.ToArray());
    }
    

    然后你可以做:

    var text = SelectedCheckBoxes.Select(cb => cb.Text).Join(", ");
    var tags = SelectedCheckBoxes.Select(cb => (string)cb.Tag).Join(", ");
    
        5
  •  0
  •   Daren Thomas    16 年前

    因为这两个函数完全相同 除了 对于getter来说,这就是你应该开始的地方:移动部分。

    还没有刷过我的C,但有点像:

        public string GetCsv(Func<string> getter)
        {
            var buffer = new StringBuilder();
            foreach (var cb in SelectedCheckBoxes)
            {
                buffer.Append(getter()).Append(",");
            }
            return DropLastComma(buffer.ToString());
        }
    

    应该工作。而且,使 SelectedCheckBoxes 变量?