Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对象实体到CSV序列化/转换_C#_.net - Fatal编程技术网

C# 对象实体到CSV序列化/转换

C# 对象实体到CSV序列化/转换,c#,.net,C#,.net,如何将所有值(属性)写入C#中的csv格式字符串? e、 g: 现在我想要一个字符串“Kevin;Kline;33” 换句话说,我想将一个对象序列化为CSV,您可以这样使用: ... PropertyInfo[] properties = obj.GetType().GetProperties(); string CSVRow = ""; foreach (PropertyInfo pi in properties) {

如何将所有值(属性)写入C#中的csv格式字符串? e、 g:

现在我想要一个字符串“Kevin;Kline;33”


换句话说,我想将一个对象序列化为CSV,您可以这样使用:

...
        PropertyInfo[] properties = obj.GetType().GetProperties();
        string CSVRow = "";
        foreach (PropertyInfo pi in properties)
        {
            CSVRow = CSVRow + pi.GetValue(obj, null) + ";";
        }
        CSVRow.Remove(CSVRow.Length - 1, 1);
...
public string ToCsv()
{
    return string.Join(";", new string[]{
        _firstName,
        _lastName,
        _age.ToString()
    }.Select(str=>Escape(str)));
}
大概是这样的:

...
        PropertyInfo[] properties = obj.GetType().GetProperties();
        string CSVRow = "";
        foreach (PropertyInfo pi in properties)
        {
            CSVRow = CSVRow + pi.GetValue(obj, null) + ";";
        }
        CSVRow.Remove(CSVRow.Length - 1, 1);
...
public string ToCsv()
{
    return string.Join(";", new string[]{
        _firstName,
        _lastName,
        _age.ToString()
    }.Select(str=>Escape(str)));
}
或者,使用反射

public static string ToCsv(this object obj)
{
    return string.Join(";",
        this.GetType().GetProperties().Select(pi=>
            Escape(pi.GetValue(this, null).ToString())
        ));
}

其中Escape是一个合适的转义函数。

通过使用反射,您可以从对象检索属性信息

foreach (PropertyInfo prp in obj.GetType().GetProperties()) {
   if (prp.CanRead) {
      object value = prp.GetValue(obj, null);
      string s = value == null ? "" : value.ToString();
      string name = prp.Name;
      ...
   }
} 
GetProperties
方法有一个重载接受
BindingFlags
,通过它可以确定需要哪种类型的属性,如private/public instance/static

你可以这样组合它们

var properties = type.GetProperties(BindingFlags.Public | 
                                    BindingFlags.NonPublic | 
                                    BindingFlags.Instance);

应用于你的问题,你可以写

List<Person> people = ...;
Type type = typeof(Person);
PropertyInfo[] properties = type.GetProperties();
var sb = new StringBuilder();

// First line contains field names
foreach (PropertyInfo prp in properties) {
   if (prp.CanRead) {
      sb.Append(prp.Name).Append(';');
   }
}
sb.Length--; // Remove last ";"
sb.AppendLine();

foreach (Person person in people) {
    foreach (PropertyInfo prp in properties) {
       if (prp.CanRead) {
          sb.Append(prp.GetValue(person, null)).Append(';');
       }
    }
    sb.Length--; // Remove last ";"
    sb.AppendLine();
}

File.AppendAllText("C:\Data\Persons.csv", sb.ToString());
列出人=。。。;
类型=类型(人);
PropertyInfo[]properties=type.GetProperties();
var sb=新的StringBuilder();
//第一行包含字段名
foreach(PropertyInfo属性中的prp){
如果(prp.CanRead){
附加(prp.Name).Append(“;”);
}
}
sb.Length——;//删除最后一个“
(某人);
foreach(人对人){
foreach(PropertyInfo属性中的prp){
如果(prp.CanRead){
sb.Append(prp.GetValue(person,null)).Append(“;”);
}
}
sb.Length;//删除最后一个“
(某人);
}
AppendAllText(“C:\Data\Persons.csv”,sb.ToString());
用双引号将字符串括起来,并通过将它们加倍来转义它们所包含的双引号,这也是一个好主意。

看看优秀的库

输出:

Kevin;Kline;33

我认为这很好,我自己也没有愤怒地使用过它,不过这是一种可能的实现,它可以读取复杂对象(深度对象序列化),例如具有对象数组属性的对象数组,并保存一个类似CSV文件格式的字符串:

private string ToCsv(string separator, IEnumerable<object> objectList)
{
    StringBuilder csvData = new StringBuilder();
    foreach (var obj in objectList)
    {
        csvData.AppendLine(ToCsvFields(separator, obj));
    }
    return csvData.ToString();
}

private string ToCsvFields(string separator, object obj)
{
    var fields = obj.GetType().GetProperties();
    StringBuilder line = new StringBuilder();

    if (obj is string)
    {
        line.Append(obj as string);
        return line.ToString();
    }

    foreach (var field in fields)
    {
        var value = field.GetValue(obj);
        var fieldType = field.GetValue(obj).GetType();

        if (line.Length > 0)
        {
            line.Append(separator);
        }
        if (value == null)
        {
            line.Append("NULL");
        }
        if (value is string)
        {
            line.Append(value as string);
        }
        if (typeof(IEnumerable).IsAssignableFrom(fieldType))
        {
            var objectList = value as IEnumerable;
            StringBuilder row = new StringBuilder();

            foreach (var item in objectList)
            {
                if (row.Length > 0)
                {
                    row.Append(separator);
                }
                row.Append(ToCsvFields(separator, item));
            }
            line.Append(row.ToString());
        }
        else
        {
            line.Append(value.ToString());
        }
    }
    return line.ToString();
}
私有字符串ToCsv(字符串分隔符,IEnumerable对象列表)
{
StringBuilder csvData=新的StringBuilder();
foreach(objectList中的var obj)
{
追加行(ToCsvFields(分隔符,obj));
}
返回csvData.ToString();
}
私有字符串ToCsvFields(字符串分隔符,对象obj)
{
var fields=obj.GetType().GetProperties();
StringBuilder行=新的StringBuilder();
if(obj是字符串)
{
行。追加(对象作为字符串);
返回行.ToString();
}
foreach(字段中的变量字段)
{
var值=字段。获取值(obj);
var fieldType=field.GetValue(obj.GetType();
如果(直线长度>0)
{
行。追加(分隔符);
}
如果(值==null)
{
行。追加(“空”);
}
if(值为字符串)
{
行。追加(值作为字符串);
}
if(typeof(IEnumerable).IsAssignableFrom(fieldType))
{
var objectList=作为IEnumerable的值;
StringBuilder行=新建StringBuilder();
foreach(objectList中的var项)
{
如果(行长度>0)
{
行追加(分隔符);
}
行追加(ToCsvFields(分隔符,项));
}
line.Append(row.ToString());
}
其他的
{
line.Append(value.ToString());
}
}
返回行.ToString();
}

您的问题需要更多的背景知识和数据/代码示例,以避免成为结案的候选。您能告诉我们您已经尝试了什么吗?@nonnb:您可以将此作为答案发布,这很有帮助。此外,这可能是一个小的挑剔,但逗号分隔值格式使用逗号分隔值。你好像在用分号,不客气。另外,由于您是StackOverflow的新手,我想通知您,您可以通过勾选答案旁边的勾号来选择好答案并接受对您帮助最大的答案。在这个网站上,投票或被接受的答案算作“谢谢”。。。。但是还需要实现引用/转义规则。是否可以使用CSVHelper,而不保存file.csv部分?我不想在Hd中写入文件,我打算将该文件作为响应发送给web用户。最好的部分是它适用于.Net Core。它很好。可惜它对.Net Core不起作用:/CSVHelper起作用!!