Dictionary Extension

Since we are doing a lot of lookup and casting, I made an extension method for Dictionary<string,object> that will try return the casted value.

using System;
using System.Collections.Generic;

namespace RPG.Core.Extensions {
    
    public static class DictionaryExtensions {

        /// <summary>
        /// This method will try to get a value from the dictionary using the provided key then cast
        /// the object as the <see cref="value"/> type.
        /// </summary>
        /// <param name="dictionary">The dictionary the value is in.</param>
        /// <param name="key">The key for the value.</param>
        /// <param name="value">The casted value.</param>
        /// <typeparam name="T">The type of the value.</typeparam>
        /// <returns>Ture if the value for the given key exists and can be
        /// cast to the provided type, otherwise returns false. </returns>
        public static bool TryGetCastValue<T>(this Dictionary<string, object> dictionary, string key, out T value) {
            if(dictionary==null){
                value = default(T);
                return false;
            }
            if(dictionary.TryGetValue(key, out var dicValue)) {
                if(dicValue is T value1){ 
                    value = value1;
                    return true;
                }
                try {
                    value = (T) Convert.ChangeType(dicValue, typeof(T));
                    return true;
                }catch(InvalidCastException) {}
            }
            value = default(T);
            return false;
        }
        
    }
    
}

I updated this to remove the redundant return.
I updated this to check if the dictionary is null.

1 Like

That’s a pretty clever setup.
You could probably remove the contents of the InvalidCastException catch as it would fall through to the identical fallback code at the end.

The handy thing about this is that it allows you a bit of versioning… for example… an old save file may save a float value, but later, you might realize you needed to save a struct with a float and a string… you can test the float/string, and if that fails, then test the bool.

Well done!

Thank you! Also, I updated the method as you suggested.

Neat, how would the “Health.cs” implementation of this look like?

Actually, I’m not sure it would ever make it to health… looking over this now, it wouldn’t be as useful in the saving system as I thought, since we’re not passing a Dictionary<string, object> to the individual components, we’re simply passing an object…

I rewrote mine to pass a dictionary.

Privacy & Terms