如果我有一个名为“Car”的对象列表:
public class Car
{
public string Name;
public int Year;
public string Model;
}
如何转换对象列表,例如列表与LT;汽车和GT;到csv?
答案 0 :(得分:14)
答案 1 :(得分:9)
将以下方法添加到Car:
String Escape(String s)
{
StringBuilder sb = new StringBuilder();
bool needQuotes = false;
foreach (char c in s.ToArray())
{
switch (c)
{
case '"': sb.Append("\\\""); needQuotes = true; break;
case ' ': sb.Append(" "); needQuotes = true; break;
case ',': sb.Append(","); needQuotes = true; break;
case '\t': sb.Append("\\t"); needQuotes = true; break;
case '\n': sb.Append("\\n"); needQuotes = true; break;
default: sb.Append(c); break;
}
}
if (needQuotes)
return "\"" + sb.ToString() + "\"";
else
return sb.ToString();
}
public void SerializeAsCsv(Stream stream)
{
stream.Write(Escape(Name));
stream.Write(",");
stream.Write(Year.ToString());
stream.Write(",");
stream.Write(Escape(Model));
stream.Write("\n");
}
现在您可以序列化整个列表:
foreach (Car car in list)
{
car.SerializeAsCsv(stream);
}
答案 2 :(得分:8)
查看FileHelpers库。
来自网站:
The FileHelpers are a free and easy to use .NET library to import/export data from fixed length or delimited records in files, strings or streams.
这将确保按行RFC-4180正确处理行终止,转义等所有类型的陷阱。
答案 3 :(得分:3)
我正在寻找一个解决方案,但我找到的答案都没有满足我的简单性。我意识到我的自动CRUD代码已经有了答案。我重新调整它并提出以下代码:
using System.Reflection;
/// <summary>
/// Using a bit of reflection to build up the strings.
/// </summary>
public static string ToCsvHeader(this object obj)
{
Type type = obj.GetType();
var properties = type.GetProperties(BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.Instance);
string result = string.Empty;
Array.ForEach(properties, prop =>
{
result += prop.Name + ",";
});
return (!string.IsNullOrEmpty(result) ? result.Substring(0, result.Length - 1) : result);
}
public static string ToCsvRow(this object obj)
{
Type type = obj.GetType();
var properties = type.GetProperties(BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.Instance);
string result = string.Empty;
Array.ForEach(properties, prop =>
{
var value = prop.GetValue(obj, null);
var propertyType = prop.PropertyType.FullName;
if (propertyType == "System.String")
{
// wrap value incase of commas
value = "\"" + value + "\"";
}
result += value + ",";
});
return (!string.IsNullOrEmpty(result) ? result.Substring(0, result.Length - 1) : result);
}
这将为每个对象添加扩展方法。用法如下:
var burgers = new List<Cheeseburger>();
var output = burgers.ToCsvHeader();
output += Environment.NewLine;
burgers.ForEach(burger =>
{
output += burger.ToCsvRow();
output += Environment.NewLine;
});
var path = "[where ever you want]";
System.IO.File.WriteAllText(path, output);
上面写这两种方法可能有更好的方法,但这对我的情况很有效。希望它可以帮到某人。
答案 4 :(得分:1)
您可以简单地覆盖ToString方法或创建ToCSVRow()方法
public String ToCSVRow()
{
return Name + "," + Year.ToString() + "," + Model;
}
然后在需要的地方做这样的事情。
using (StreamWriter file = new StreamWriter(@"C:\Wherever\yourfilename.txt"))
{
foreach (var item in yourlist)
{
file.WriteLine(item.ToCSVRow());
}
}
答案 5 :(得分:0)
将逗号分隔的值放在一起我总是喜欢指向被低估的string.Join(string separator, string[] elements)
静态方法,但如果有辅助库,那可能是更好的东西。
答案 6 :(得分:0)
我按照article实现了一些额外的序列化行为。如果您想获得幻想,可以在项目属性中创建一个设置。此设置将确定您的类是使用csv还是默认的序列化。然后,您可以通过here显示的技术访问它。考虑使用静态构造函数来读取appsettings并使一个布尔值可以访问序列化代码。 Vlads的代码看起来很棒,只需将其插入代码即可。此外,您还可以考虑其他更好的方法来改变序列化行为。
或者创建一个名为“SerializeAsCSV”的接口,并使用它类似:
// MyCoolClass.csv的部分内容:
public class MyCoolClass : ISerializeAsCSV, IDisposable
{
protected static bool serializesToCSV = false;
static MyCoolClass()
{
serializesToCSV =
(typeof(MyCoolClass).GetInterface("GrooveySoft.Shared.Interfaces.ISerializeAsCSV") == null)
? false
: true;
}
public MyCoolClass(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
// your stuff here
}
public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
// your stuff here
}
}
// ISerializeAsCSV.cs的内容
using System.Runtime.Serialization;
namespace GrooveySoft.Shared.Interfaces
{
/// <summary>
/// indicates that implementor will serialize to csv format
/// </summary>
public interface ISerializeAsCSV : ISerializable
{
}
}
这应该让你开始。 。 。我没有编译和测试过这个。 。但你得到了一般的想法。
答案 7 :(得分:0)
另一个选项是Linq to CSV,这是NuGet提供的一个软件包。有关示例用法,请参阅Combine contents of two files using LINQ to CSV。