簡體   English   中英

序列化TSV類的特定屬性

[英]Serialize specific properties of a class for TSV

我有以下類型的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時考慮特定的屬性。 在這種情況下,我只需要IdNamePhone

我用來轉換為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();
}

我不想靜態提及/硬編碼要考慮的字段,因為它們將來可能會更改。 我該如何實現?

即使您沒有使用外部庫來創建TSV,您仍然可以使用屬性來標記特殊屬性(例如,那些遺漏的屬性)。 然后,您可以使用反射來檢查現有的屬性和屬性。

這是一個完整的示例:

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從循環中移出到私有成員(計算一次)的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM