我正在创建一个从网络服务获取燃油价格的应用程序。我想以价格对象的IDictionary反序列化,以燃料为关键字(类似于this)。
我创建了一个setter来执行此操作,但后来发现序列化使用Add方法而不是列表的setter。有没有办法使用序列化API执行此操作,还是必须编写自定义序列化代码?
XML看起来像这样
<?xml version="1.0"?>
<prices>
<price fuel="Petrol">152.43</price>
<price fuel="Diesel">147.53</price>
</prices>
代码看起来像这样
[XmlRoot("prices")]
public class FuelPrices
{
private IDictionary<Fuel, Price> prices = new Dictionary<Fuel, Price>();
// This is used for serialising to XML
[XmlElement("price")]
public ICollection<Price> Prices
{
get
{
return prices.Values;
}
set
{
prices = new Dictionary<Fuel, Price>();
foreach (Price price in value)
{
prices[price.Fuel] = price;
}
}
}
// These properties are used to access the prices in the code
[XmlIgnore]
public Price PetrolPrice
{
get
{
Price petrolPrice;
prices.TryGetValue(Fuel.Petrol, out petrolPrice);
return petrolPrice;
}
}
[XmlIgnore]
public Price DieselPrice
{
get
{
Price dieselPrice;
prices.TryGetValue(Fuel.Diesel, out dieselPrice);
return dieselPrice;
}
}
}
答案 0 :(得分:1)
你可以沿着
的方式在字典周围写一个包装器sealed class DictionaryWrapper<K, T> : ICollection<T>
{
private readonly Func<T, K> m_keyProjection ;
private readonly IDictionary<K, T> m_dictionary ;
// expose the wrapped dictionary
public IDictionary<K, T> Dictionary { get { return m_dictionary ; }}
public void Add (T value)
{
m_dictionary[m_keyProjection (value)] = value ;
}
public IEnumerator<T> GetEnumerator ()
{
return m_dictionary.Values.GetEnumerator () ;
}
// the rest is left as excercise for the reader
}
并像这样使用
private DictionaryWrapper<Fuel, Price> pricesWrapper =
new DictionaryWrapper<Fuel, Price> (
new Dictionary<Fuel, Price> (), price => price.Fuel) ;
[XmlElement("price")]
public ICollection<Price> Prices
{
get { return pricesWrapper ; } // NB: no setter is necessary
}
答案 1 :(得分:0)
如果您不想编写自定义序列化 - 您可以这样做:
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
namespace ConsoleApplication2
{
public class Program
{
[XmlType("price")]
public class Price
{
[XmlText]
public double price { get; set; }
[XmlAttribute("fuel")]
public string fuel { get; set; }
}
[XmlType("prices")]
public class PriceList : List<Price>
{
}
static void Main(string[] args)
{
//Serialize
var plist = new PriceList()
{
new Price {price = 153.9, fuel = "Diesel"},
new Price {price = 120.6, fuel = "Petrol"}
};
var serializer = new XmlSerializer(typeof(PriceList));
var sw = new StringWriter();
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
serializer.Serialize(sw, plist, ns);
var result = sw.ToString();//result xml as we like
//Deserialize
var sr = new StringReader(result);
var templist = (PriceList)serializer.Deserialize(sr);
var myDictionary = templist.ToDictionary(item => item.fuel, item => item.price);
}
}
}
如果您需要自定义序列化,请查看以下帖子:Why isn't there an XML-serializable dictionary in .NET?