slavacademy
slavacademy

Reputation: 677

C# Generics "Cannot convert System.ValueType to T" (Unity Prefs)

I have this function which get's the following error in the compiler: cannot convert System.ValueType to T and the typeof(string) block gives the error: cannot convert type 'string' to 'T'

public static T ReadKey<T>(GamePrefs.Key k, T defaultValue)
    {
        T obj = defaultValue;
        if (typeof(T) == typeof(bool))
            obj = (T)(ValueType)(bool)(PlayerPrefs.GetInt(k.ToString(), !(bool)(object)defaultValue ? 0 : 1) == 1 ? true : false);
        else if (typeof(T) == typeof(int))
            obj = (T)(ValueType)PlayerPrefs.GetInt(k.ToString(), (int)(object)defaultValue);
        else if (typeof(T) == typeof(float))
            obj = (T)(ValueType)PlayerPrefs.GetFloat(k.ToString(), (float)(object)defaultValue);
        else if (typeof(T) == typeof(string))
            obj = (T)PlayerPrefs.GetString(k.ToString(), (string)(object)defaultValue);
        else
            Debug.LogError((object)string.Format("Key {0} couldn't be read because type {1} not supported.", (object)k, (object)typeof(T)));
        return obj;
    }

What's the problem in here?

Upvotes: 1

Views: 1604

Answers (2)

Alex
Alex

Reputation: 7919

Your code is very overcomplicated - there is no need for a generic parameter. The type is known at compile-time. Create four overloaded methods:

public static bool ReadKey(GamePrefs.Key k, bool defaultValue)
{
    return PlayerPrefs.GetInt(k.ToString(), defaultValue ? 1 : 0) == 1;
}

public static int ReadKey(GamePrefs.Key k, int defaultValue)
{
    return PlayerPrefs.GetInt(k.ToString(), defaultValue);
}

public static float ReadKey(GamePrefs.Key k, float defaultValue)
{
    return PlayerPrefs.GetFloat(k.ToString(), defaultValue);
}

public static string ReadKey(GamePrefs.Key k, string defaultValue)
{
    return PlayerPrefs.GetString(k.ToString(), defaultValue);
}

Upvotes: 3

slavacademy
slavacademy

Reputation: 677

This did the trick, no errors:

public static T ReadKey<T>(GamePrefs.Key k, T defaultValue)
    {
        T obj = defaultValue;
        if (typeof(T) == typeof(bool))
            obj = (T)Convert.ChangeType((bool)(PlayerPrefs.GetInt(k.ToString(), !(bool)(object)defaultValue ? 0 : 1) == 1 ? true : false), typeof(T));
        else if (typeof(T) == typeof(int))
            obj = (T)Convert.ChangeType((PlayerPrefs.GetInt(k.ToString(), (int)(object)defaultValue)), typeof(T));
        else if (typeof(T) == typeof(float))
            obj = (T)Convert.ChangeType((PlayerPrefs.GetFloat(k.ToString(), (float)(object)defaultValue)), typeof(T));
        else if (typeof(T) == typeof(string))
            obj = (T)Convert.ChangeType((PlayerPrefs.GetString(k.ToString(), (string)(object)defaultValue)), typeof(T));
        else
            Debug.LogError((object)string.Format("Key {0} couldn't be read because type {1} not supported.", (object)k, (object)typeof(T)));
        return obj;
    }

Upvotes: 1

Related Questions