【问题标题】:C# Generics "Cannot convert System.ValueType to T" (Unity Prefs)C# 泛型“无法将 System.ValueType 转换为 T”(Unity Prefs)
【发布时间】:2014-07-29 14:44:13
【问题描述】:

我有这个函数,它在编译器中得到以下错误:cannot convert System.ValueType to T 并且 typeof(string) 块给出错误:cannot convert type 'string'到'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;
    }

这里有什么问题?

【问题讨论】:

  • Debug.LogError((object)string.Format("Key {0} couldn't be read because type {1} not supported.", (object)k, (object)typeof(T))); Format 调用 ToString 方法。可能值得一看 GetType() 而不是 typeof
  • 我会在类似的问题中指出 Eric Lippert 的 this answer
  • 第一个if下的那行里面有各种wtf,可以换成obj = (bool)(PlayerPrefs.GetInt(k.ToString(), defaultValue ? 1 : 0) == 1);,不知道能不能解决你的问题。
  • 说:无法将类型'T'隐式转换为'bool'(参数defaultValue)

标签: c# generics unity3d


【解决方案1】:

您的代码非常复杂 - 不需要泛型参数。该类型在编译时是已知的。创建四个重载方法:

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);
}

【讨论】:

  • 它有效。是的,这很复杂,我认为在我的情况下使用泛型会更容易,我想我错了。
【解决方案2】:

这成功了,没有错误:

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;
    }

【讨论】:

  • 你投的太多了。你仍然会从Tobject 回到本质上的T。您应该能够删除object 的强制转换。对您的GetXType 调用也感到非常困惑,我认为它会返回它所说的类型,但随后您将其传递给Convert.ChangeType
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-01
  • 1970-01-01
相关资源
最近更新 更多