2016-09-20 19 views
0

一類的特定性能我有一個以下類型序列化TSV

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; } 
} 

的POCO我有Person S的我要轉換爲TSV(製表符分隔值)的列表。但我只希望在創建TSV時考慮特定的屬性。在這種情況下,我只需要Id,NamePhone

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

我不想提靜態/硬編碼領域來考慮,因爲它們可能在將來改變。我怎樣才能做到這一點?

回答

1

即使您沒有使用外部庫創建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}"); 
     } 
    } 
} 

此代碼enumarates的POCO類的所有性的判定,檢查他們是否有特定的屬性,離開了這些,並輸出休息。

您可以根據自己的意願定義自己的屬性,這裏我剛剛使用了System.Runtime.Serialization(用於類似目的)的IgnoreDataMember

請注意,檢查現有屬性和屬性是使用反射,應該小心使用反射。性能可能是一個問題,如果代碼多次運行大數據集,它可能會很慢 - 這就是爲什麼我將personProperties從循環中移出到一個私有成員(計算一次)的原因。

+0

目前我沒有使用任何庫。我已經更新了上面的問題,關於我如何做。 – SohamC

+0

您仍然可以在這種情況下使用屬性,但是您必須自己檢查屬性。我已經用這種方式編輯了我的答案,請檢查。 –