我有一个类Wrapper
,它的字典属性为DictA
,我想在将新项添加到字典后立即序列化该类的实例。但是,当我在DictA
中插入新项目时,DictA
属性设置器将不会执行。我认为,我缺少字典的一些基本行为,需要帮助以了解它。下面是示例代码,我正在使用...
public class Product
{
public string Name { get; set; }
public DateTime Expiry { get; set; }
public string[ ] Sizes { get; set; }
}
public class Wrapper : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Dictionary<string, Product> dictA_;
public Wrapper() => dictA_ = new Dictionary<string, Product>();
public Dictionary<string, Product> DictA
{
get => dictA_;
set
{
dictA_ = value;
SerializeToJson(); // trying to serialize in simple fashion without event handling
}
}
public void SerializeToJson()
{
string path = @"..\JsonTest.json"; // path
string json = JsonConvert.SerializeObject( this );
JsonSerializer serializer = new JsonSerializer( );
using(StreamWriter sw = new StreamWriter(path))
{
using(JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize( writer, this );
}
}
}
}
public static void Main(string[] args)
{
var product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Sizes = new string[] {"Small"};
var temp = new Wrapper();
temp.DictA.Add("test", product);
Thread.Sleep(1000 * 15);
temp.DictA.Add("test2", product);
Thread.Sleep(1000 * 15);
temp.DictA.Add("test3", product);
Console.ReadKey();
}
答案 0 :(得分:3)
设置器仅用于将对字典的引用分配给该属性。与将值添加到属性引用的任何字典无关。
如果希望在将新值添加到字典时发生某些逻辑,则应编写自己的实现IDictionary<TKey, TValue>
的类。使用现有的Dictionary<TKey, TValue>
实现来支持它,但是在将值添加到字典之前,请在Add
方法实现中执行自己的逻辑。
答案 1 :(得分:1)
正如评论所说,您要添加到集合中,而不是设置集合的值,一个好的解决方案是创建一个自定义类并从Dictionary继承,这样做可以解决您的问题:
class SerialisableDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
public new void Add(TKey key, TValue value)
{
base.Add(key, value);
SerializeToJson();
}
}
答案 2 :(得分:0)
最后,我设法找到了所需的解决方案。请检查,如果有错误,请突出显示它:
public class Product {
public string Name { get; set; }
public DateTime Expiry { get; set; }
public string[ ] Sizes { get; set; }
}
public class DictionaryWithJsonSerailization<TKey, TValue> : IDictionary<TKey, TValue>, INotifyPropertyChanged {
#region Events
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region Private fields
Dictionary<TKey, TValue> _interalDictionary;
#endregion
#region Constructor
public DictionaryWithJsonSerailization( ) {
_interalDictionary = new Dictionary<TKey, TValue>( );
}
#endregion
#region implementation of IDictionary<TKey, TValue> interface
public TValue this[ TKey key ] {
get {
try {
return ( TValue )_interalDictionary[ key ];
}
catch( Exception ex ) {
return default( TValue );
}
}
set {
_interalDictionary[ key ] = value;
NotifyObserversOfChange( );
}
}
public ICollection<TKey> Keys {
get {
return _interalDictionary.Select( x => ( TKey )x.Key ).ToList( );
}
}
public ICollection<TValue> Values {
get {
return _interalDictionary.Select( x => ( TValue )x.Value ).ToList( );
}
}
public int Count {
get {
return _interalDictionary.Count;
}
}
public bool IsReadOnly {
get {
return false;
}
}
public void Add( TKey key, TValue value ) {
_interalDictionary.Add( key, value );
NotifyObserversOfChange( );
}
public void Add( KeyValuePair<TKey, TValue> item ) {
_interalDictionary.Add( item.Key, item.Value );
NotifyObserversOfChange( );
}
public void Clear( ) {
_interalDictionary = new Dictionary<TKey, TValue>( );
NotifyObserversOfChange( );
}
public bool Contains( KeyValuePair<TKey, TValue> item ) {
return _interalDictionary.Contains( item );
}
public bool ContainsKey( TKey key ) {
return _interalDictionary.ContainsKey( key );
}
public void CopyTo( KeyValuePair<TKey, TValue>[ ] array, int arrayIndex ) {
throw new NotImplementedException( );
}
public bool Remove( TKey key ) {
try {
_interalDictionary.Remove( key );
NotifyObserversOfChange( );
return true;
}
catch( Exception ex ) {
return false;
}
}
public bool Remove( KeyValuePair<TKey, TValue> item ) {
try {
_interalDictionary.Remove( item.Key );
NotifyObserversOfChange( );
return true;
}
catch( Exception ex ) {
return false;
}
}
public bool TryGetValue( TKey key, out TValue value ) {
try {
value = ( TValue )_interalDictionary[ key ];
return true;
}
catch( Exception ex ) {
value = default( TValue );
return false;
}
}
IEnumerator IEnumerable.GetEnumerator( ) {
return ( ( IDictionary<TKey, TValue> )this ).GetEnumerator( );
}
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator( ) {
return _interalDictionary.GetEnumerator( );
}
#endregion
#region Private methods
private void NotifyObserversOfChange( ) {
var propertyHandler = PropertyChanged;
if( propertyHandler != null ) {
if( propertyHandler != null ) {
propertyHandler( this, new PropertyChangedEventArgs( "Count" ) );
propertyHandler( this, new PropertyChangedEventArgs( "Keys" ) );
propertyHandler( this, new PropertyChangedEventArgs( "Values" ) );
propertyHandler( this, new PropertyChangedEventArgs( "this" ) );
}
}
}
public IEnumerator GetEnumerator( ) {
throw new NotImplementedException( );
}
#endregion
}
public class Wrapper {
DictionaryWithJsonSerailization<string, Product> dictA_;
public Wrapper( ) {
dictA_ = new DictionaryWithJsonSerailization<string, Product>( );
dictA_.PropertyChanged += ( sener, i ) => SerializeToJson( );
}
public DictionaryWithJsonSerailization<string, Product> DictA {
get {
return dictA_;
}
set {
dictA_ = value;
}
}
public void SerializeToJson( ) {
string path = @"...\JsonTest.json";
string json = JsonConvert.SerializeObject( this );
JsonSerializer serializer = new JsonSerializer( );
using( StreamWriter sw = new StreamWriter( path ) ) {
using( JsonWriter writer = new JsonTextWriter( sw ) ) {
serializer.Serialize( writer, this );
}
}
}
}
static void Main( string[ ] args ) {
Product product = new Product( );
product.Name = "Apple";
product.Expiry = new DateTime( 2008, 12, 28 );
product.Sizes = new string[ ] { "Small" };
var temp = new Wrapper( );
temp.DictA.Add( "test", product );
Thread.Sleep( 1000 * 15 );
temp.DictA.Add( "test2", product );
Thread.Sleep( 1000 * 15 );
temp.DictA.Add( "test3", product );
}
我试图在字典中延迟一段时间后添加项目,并且每当有新项目添加到字典中时,具有该字典的对象就会存储在计算机驱动器上的json文件中。