我有一个以下类型的POCO
public class Person{
public Guid Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int PinCode { get; set; }
public string Phone { get; set; }
}
我有一个Person
的列表,我想将其转换为TSV(制表符分隔值)。但我只想在创建TSV时考虑特定属性。在这种情况下,我只想要Id
,Name
和Phone
。
我用来转换为TSV的代码如下
public string Serialize(string separator, IEnumerable<Person> objectlist)
{
string[] fields = new[] { "Id", "Name", "Phone" };
StringBuilder tsvdata = new StringBuilder();
string header = string.Join(separator, fields);
tsvdata.AppendLine(header);
foreach (var o in objectlist)
tsvdata.AppendLine(o.Id + separator + o.Person + separator + o.Phone);
return tsvdata.ToString();
}
我不想静态提及/硬编码要考虑的字段,因为它们将来可能会发生变化。我怎样才能做到这一点?
答案 0 :(得分:1)
即使您没有使用外部库来创建TSV,您仍然可以使用属性来标记特殊属性(例如那些被遗漏的属性)。然后,您可以使用 reflection 来检查现有的属性和属性。
这是一个完整的例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
namespace ConsoleApplication1
{
public class Person
{
[DataMember]
public Guid Id { get; set; }
[DataMember]
public string Name { get; set; }
[IgnoreDataMember]
public string Address { get; set; }
[IgnoreDataMember]
public int PinCode { get; set; }
[DataMember]
public string Phone { get; set; }
}
class Program
{
// list of properties of Person class marked with DataMemeber attribute
private PropertyInfo[] _personProperties = typeof(Person)
.GetProperties()
.Where(x => x.GetCustomAttribute(typeof(DataMemberAttribute)) != null).ToArray();
public string Serialize(string separator, IEnumerable<Person> objectlist)
{
StringBuilder tsvdata = new StringBuilder();
string header = string.Join(separator, _personProperties.Select(x => x.Name).ToArray());
tsvdata.AppendLine(header);
foreach (var o in objectlist)
{
List<string> lineValues = new List<string>();
// enumerate through the properties
foreach (var pi in _personProperties)
{
lineValues.Add(pi.GetValue(o).ToString());
}
tsvdata.AppendLine(string.Join(separator, lineValues.ToArray()));
}
return tsvdata.ToString();
}
static void Main(string[] args)
{
Program p = new Program();
List<Person> persons = new List<Person> {
new Person { Id = Guid.NewGuid(), Address = "a1", Name = "name1", Phone = "tel1", PinCode = 1111 },
new Person { Id = Guid.NewGuid(), Address = "a2", Name = "name2", Phone = "tel2", PinCode = 2222 },
};
string serializedString = p.Serialize(", ", persons);
Console.WriteLine($"result: {serializedString}");
}
}
}
此代码包含了POCO类的所有属性,检查它们是否具有特定属性,遗漏了那些属性,并输出其余属性。
您可以根据需要定义自己的属性,这里我刚刚使用System.Runtime.Serialization中的 IgnoreDataMember (用于类似目的)。
请注意,检查现有属性和属性是使用反射,应谨慎使用。性能可能是一个问题,如果代码多次运行大型数据集,它可能会很慢 - 这就是我将personProperties从循环中放到私有成员(计算一次)的原因。