将对象转换为逗号分隔字符串

7

有没有办法使一个对象中的逗号分隔开。请注意,这是对象而不是对象列表。

例如:

public class EmployeeLogReportListViewModel
{
    public DateTime Date { get; set; }
    public int EmployeeID { get; set; }
    public TimeSpan Time { get; set; }
    public int Sort { get; set; }
    public string Employer { get; set; }
}

以下是相关数值

Date = "2018/02/03"
EmployeeID = 111
Time = 11:53 AM
Sort = 1
Employer = EMP

这应该导致的结果是:
2018/02/03,111,11:53 AM,1 EMP

什么是使这行代码成为可能的最佳方法?我不想使用string builder并将所有内容附加到它上面。

你将如何使用它? - Backs
你在这里想要实现什么目标? - Sriman Saswat Suvankar
@Backs会将其放在字符串列表中。 - Rashid
请提供编辑后的文本。 - Rashid
4个回答

16
我觉得你正在寻找重写的 `.ToString()` 方法。你需要修改类的代码如下:
public class EmployeeLogReportListViewModel
{
    public DateTime Date { get; set; }
    public int EmployeeID { get; set; }
    public TimeSpan Time { get; set; }
    public int Sort { get; set; }
    public string Employer { get; set; }
    public override string ToString()
    {
        return String.Format("{0},{1},{2},{3},{4}", this.Date, this.EmployeeID, this.Time, this.Sort, this.Employer);
    }
}

使用示例

EmployeeLogReportListViewModel objVm = new EmployeeLogReportListViewModel();
// Assign values for the properties
objVm.ToString(); // This will give you the expected output

可以将String.Format()替换为以下的字符串插值形式
public override string ToString()
{
  // return $"Date:{this.Date},EmployeeID:{this.EmployeeID},Time:{this.Time},Sort:{this.Sort},Employer:{this.Employer}";
  // To get the mentioned OP. ie., 2018/02/03,111,11:53 AM,1 EMP
  return $"{this.Date.ToString("yyyy/mm/dd")},{this.EmployeeID},{this.Time.ToString("hh:mm tt")},{this.Sort},{this.Employer}";
}

2
字符串插值也可以用于 C# 6。 - Sweeper
1
@SecretCoder 如果明天你想向类中添加一个新属性,你就必须更改 override ToString() 方法。如果你没有处理它,新开发人员来了,只是忘记了覆盖 ToString()。这可能会在很多地方引起错误/漏洞。这只是一个想法。 - Sriman Saswat Suvankar
我喜欢这个例子的原因是它允许您控制生成的分隔字符串中值的顺序。 - Mike Murphy

12

有挑战就要接受

var o = new EmployeeLogReportListViewModel();
var text = string.Join
(
    ",",
    typeof(EmployeeLogReportListViewModel)
        .GetProperties(BindingFlags.Instance | BindingFlags.Public)
        .Select
        (
            prop => prop.GetValue(o).ToString()
        )
);
Console.WriteLine(text);

从技术上讲,那是一行代码。

如果你想按字母顺序排序属性,你可以使用这个:

var o = new EmployeeLogReportListViewModel();
var text = string.Join
(
    ",",
    typeof(EmployeeLogReportListViewModel)
        .GetProperties(BindingFlags.Instance | BindingFlags.Public)
        .OrderBy( prop => prop.Name )
        .Select
        (
            prop => prop.GetValue(o).ToString()
        )
);
Console.WriteLine(text);

这个答案在可扩展性方面最适合。当您向类添加属性时,它可以在不更改任何内容的情况下工作。目前它会抛出一个空引用异常,因为Employer为空。为了使用它,我们必须确保类的所有属性都不为空。否则我们会得到空引用。 - Sriman Saswat Suvankar
我喜欢这种方法,但如果你想按特定顺序排列它们,你会如何修改它? - Mike Murphy
@MikeMurphy 在 Select 前添加一个 OrderBy 子句。 - John Wu
这段代码正是我所需要的。我会将它添加到我的库中并给予John Wu荣誉。非常感谢! - Lynn

2

回复有点晚,但我可以想象你想要以某种csv输出样式进行操作

一个好的通用方法是创建一个扩展方法,将任何Enumerable转换为csv字符串。

所以借鉴@John Wu的解决方案,我们得到如下内容:

public static class EnumerableToCsvExtension
{
    public static string ToCSVString<TContent>(this IEnumerable<TContent> enumerable, char propertySeparator = ',', bool includeHeader = true)
    {
        var properties = typeof(TContent).GetProperties(BindingFlags.Instance | BindingFlags.Public);

        var header = string.Join(propertySeparator, properties.Select(p => p.Name));
        var rows = enumerable.ToList().ConvertAll(item => string.Join(propertySeparator, properties.Select(p => p.GetValue(item) ?? string.Empty )));

        var csvArray = includeHeader ? rows.Prepend(header) : rows;

        return string.Join(Environment.NewLine, csvArray);
    }
}

然后你可以像这样使用它。
var list = new List<EmployeeLogReportListViewModel> { new EmployeeLogReportListViewModel(), new EmployeeLogReportListViewModel() };
list.ToCSVString();
list.ToCSVString(propertySeparator: '|', includeHeader: false);

有没有一种方法可以指定结果分隔字符串中值的顺序? - Mike Murphy
1
@MikeMurphy 可以通过添加一个额外的参数,如params string[] order,然后对properties数组进行排序来轻松完成。为此,请查看如何在c#中对列表进行排序并发挥您的想象力 :) 参见:https://dev59.com/q3I-5IYBdhLWcg3wN1hD - Nicollas Braga
现在,如果你的问题是关于按名称排序,你可以使用 OrderBy 或者 OrderByDescending。 - Nicollas Braga

0
你可以像下面这样使用:
public class bKashAccountInfo
{
    public string bKashNumber { get; set; }
    public string bKashAccountType { get; set; }

    public override string ToString()
    {
        return String.Format($"bKash Number-{bKashNumber}, Account Type - {bKashAccountType}");
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接