2017-05-08 21 views
3

我定義這個簡單類型:用戶定義的結構和默認(德)序列化

public struct Price : IComparer<Price>, IEquatable<Price> { 

    private readonly decimal _value; 

    public Price(Price value) { 
     _value = value._value; 
    } 

    public Price(decimal value) { 
     _value = value; 
    } 

    public int Compare(Price x, Price y) { 
     return x._value.CompareTo(y._value); 
    } 

    public int Compare(Price x, decimal y) { 
     return x._value.CompareTo(y); 
    } 

    public int Compare(decimal x, Price y) { 
     return x.CompareTo(y._value); 
    } 

    public bool Equals(Price other) { 
     return _value.Equals(other._value); 
    } 

    public override bool Equals(object obj) { 
     if (ReferenceEquals(null, obj)) 
      return false; 
     return obj is Price && Equals((Price)obj); 
    } 

    public override int GetHashCode() { 
     return _value.GetHashCode(); 
    } 

    public static implicit operator decimal(Price p) { 
     return p._value; 
    } 

    public static implicit operator Price(decimal d) { 
     return new Price(d); 
    } 
} 

當我反序列化JSON給來Price它工作得很好。但是當我試圖序列化時,它會返回一個空的{ }。我的意思是,假設有這種模式:

public class Product { 
    public string Name { get; set; } 
    public Price Price { get; set; } 
} 

deserializng一個JSON這樣的:

{ "Name": "Some name", "Price": 2.3 } 

給了我正確的對象。但是序列化這個示例:

var p = new Product { Name = "Some name", Price = 2.3 } 

創建該JSON:

{ "Name": "Some name", "Price": { } } 

那麼,如何我能做告訴串行器庫(例如Json.NET和吉爾)如何序列化我的自定義類型是什麼?

UPDATE:

樣品序列化代碼,使用Json.NET

var s = JsonConvert.SerializeObject(p); 

UPDATE2: 我不希望依賴於Json.NET或任何其他第三方庫。因此,在Json.NET中使用JsonConverter並不是答案。提前致謝。

+0

你能提供你當前的序列化代碼嗎? –

+0

您確定這是有效的嗎?價格= 2.3。你不需要新建結構? – Thangadurai

+1

@Thangadurai隱式運算符'公共靜態隱式運算符價格(十進制d)'照顧那 –

回答

2

眼下串行不知道如何序列化你的結構,你需要告訴它如何做到這一點。這是怎麼做的Json.NET

一種方法是添加JsonPropertyAttribute_value。這將導致像這樣的json

{"Name":"Some Name","Price":{"_value":2.3}} 

另一種方法是創建自己的JsonConverter,將您的價格作爲小數處理。一個簡單的方法可以是這樣的

class PriceConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(decimal?); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     return serializer.Deserialize(reader) as Price?; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     serializer.Serialize(writer, (decimal)((Price)value)); 
    } 
} 

而且你將需要JsonConverterAttribute上你的結構

[JsonConverter(typeof(PriceConverter))] 
struct Price 
{ 
    //... 
} 

這會給你JSON這樣

{"Name":"Some Name","Price":2.3} 

兩種方式進行序列化和反序列化精,但第二個更好地閱讀json。

+0

謝謝。但請參閱最新的答案。 –

1

您可以通過實施對象的ISerializable接口自定義序列化過程。這在成員變量的值在反序列化後無效的情況下特別有用,但您需要爲該變量提供一個值以重建對象的完整狀態。實現ISerializable涉及實現GetObjectData方法和一個將在對象反序列化時使用的特殊構造函數。

的示例下面的代碼演示如何實現ISerializable的。

public struct Price : IComparer<Price>, IEquatable<Price>, ISerializable 
{ 

    private readonly decimal _value; 

    public Price(Price value) 
    { 
     _value = value._value; 
    } 

    public Price(decimal value) 
    { 
     _value = value; 
    } 

    public int Compare(Price x, Price y) 
    { 
     return x._value.CompareTo(y._value); 
    } 

    public int Compare(Price x, decimal y) 
    { 
     return x._value.CompareTo(y); 
    } 

    public int Compare(decimal x, Price y) 
    { 
     return x.CompareTo(y._value); 
    } 

    public bool Equals(Price other) 
    { 
     return _value.Equals(other._value); 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) 
      return false; 
     return obj is Price && Equals((Price)obj); 
    } 

    public override int GetHashCode() 
    { 
     return _value.GetHashCode(); 
    } 

    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("Value", _value); 
    } 

    public static implicit operator decimal(Price p) 
    { 
     return p._value; 
    } 

    public static implicit operator Price(decimal d) 
    { 
     return new Price(d); 
    } 
} 
+0

我認爲這是讓圖書館獨立的唯一方法。 – Mats391

相關問題