c # – A property for Unity that is serialized into a string

This one dictionary I can join GameObject and that is serializable because Unity can not serialize them by default.

I decided to use TypeDescriptor Conversion of any kind of convertible objects, instead of numerous overloads such getInt, GetFloat, GetBool, GetString,

Small disadvantage: since it is naturally slower TypeDescriptor uses reflection.

I decided not to implement IDictionary for many reasons:

  • expose key Property would be confusing because values ​​are not all line
  • the enumerator also makes little sense if he does not return object values
  • There are many members I will never use

It works as expected, simple and straightforward, but improvements are welcome!

with system;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using JetBrains.Annotations;
with UnityEngine;

Namespace ZeroAG.Scene
{
    [SuppressMessage("ReSharper", "IdentifierTypo")]
    Public class PropertySet: MonoBehaviour, IPropertySet, ISerializationCallbackReceiver
{
internal const string DictionaryKeysProperty = nameof (_dictionaryKeys);
internal const string DictionaryValsProperty = nameof (_dictionaryVals);

private dictionary _dictionary = new dictionary();

        [SerializeField]
        [HideInInspector]
        
        
        
        private list _dictionaryKeys = new list();

        [SerializeField]
        [HideInInspector]
        
        
        
        private list _dictionaryVals = new list();

#region IPropertySet members

public void delete ()
{
_dictionary.Clear ();
}

public bool ContainsKey (String key)
{
if (key == null)
Throw new ArgumentNullException (nameof (key));

return _dictionary.ContainsKey (key);
}

public T GetValue(String key)
{
if (key == null)
Throw new ArgumentNullException (nameof (key));

var converter = TypeDescriptor.GetConverter (typeof (T));

if (! converter.CanConvertFrom (typeof (string)))
Do not throw new InvalidCastException ($ "conversion from {typeof (string)}) to {typeof (T)}.");

var value = _dictionary[key];

var o = converter.ConvertFromInvariantString (value);
if (o is T result)
Return result;

New InvalidCastException throw ($ "The converted value is not of type {typeof (T)}.");
}

public bool Remove (string key)
{
if (key == null)
Throw new ArgumentNullException (nameof (key));

return _dictionary.Remove (key);
}

public void SetValue(String key, T value)
{
if (key == null)
Throw new ArgumentNullException (nameof (key));

if (value == null)
Throw new ArgumentNullException (nameof (value));

var converter = TypeDescriptor.GetConverter (typeof (T));

if (! converter.CanConvertTo (typeof (string)))
New InvalidOperationException ($ "Unable to cast {typeof (T)} into {typeof (string)})");

var result = converter.ConvertToInvariantString (value);

AddOrUpdate (key, result);
}

public bool TryGetValue(String key, Out T result)
{
if (key == null)
Throw new ArgumentNullException (nameof (key));

To attempt
{
Result = GetValue(Key);
return true;
}
fishing
{
Result = standard (T);
return it incorrectly;
}
}

#endregion

#region ISerializationCallbackReceiver members

void ISerializationCallbackReceiver.OnAfterDeserialize ()
{
_dictionary = _dictionaryKeys.Zip (_dictionaryVals, (k, v) => new {k, v}). ToDictionary (s => s.k, s => s.v);
}

void ISerializationCallbackReceiver.OnBeforeSerialize ()
{
_dictionaryKeys = _dictionary.Keys.ToList ();
_dictionaryVals = _dictionary.Values.ToList ();
}

#endregion

private void AddOrUpdate ([NotNull] String key, string value)
{
if (key == null)
Throw new ArgumentNullException (nameof (key));

if (_dictionary.ContainsKey (key))
{
_Dictionary[key] = Value;
}
otherwise
{
_dictionary.Add (key, value);
}
}
}
}