事件起因
如果您正好学到 PlayerPrefs 这里,不妨一起讨论一下。也希望有大佬可以更加详细的解释一下!!
提前感谢了!
在进行 PlayerPrefs 的实践小项目的学习中,突然就遇到了一个很是困扰我的问题:
以下是代码:
代码一:
//主要功能:加载存入硬盘的数据
public object LoadDate(Type type, string keyName)
{
//根据传入的 Type 创建一个对象 用于存入数据
object date = Activator.CreateInstance(type);
//要往 new 出来的对象 填充数据
//得到所有字段
FieldInfo[] fields = type.GetFields();
//用于 拼接key的字符串
string loadKeyName = "";
FieldInfo info;
for (int i = 0; i < fields.Length; i++)
{
//得到一个字段信息
info = fields[i];
//key
loadKeyName = keyName + "_" + type.Name + "_" + info.FieldType.Name + "_" + info.Name;
//有 key 就可以得到 value
object o = LoadValue(info.FieldType, loadKeyName);
info.SetValue(date, o);
}
return date;
}
代码二:被 代码一 调用
private object LoadValue(Type field, string keyName)
{
//根据字段类型来判断用哪个api来读取
//类型判断
//判断是不是int
if (field == typeof(Int32))
{
return PlayerPrefs.GetInt(keyName, 0);
}
else
{
return null;
}
}
打眼一看,是没有什么问题的。
注意:代码是跟着 老Tang 敲的,某得问题,只不过为了方便阅读,截取了一部分!在做数据存入的时候,我是没感觉出来任何的问题的。
直到做到 数据的读取,我是越做越感觉不对劲!!!
问题就出在这一行代码:
在 代码一 中的:
//有 key 就可以得到 value
object o = LoadValue(info.FieldType, loadKeyName);
info.SetValue(date, o);
在 代码二 中的:
//类型判断
//判断是不是int
if (field == typeof(Int32))
{
return PlayerPrefs.GetInt(keyName, 0);
}
您老看,通过 LoadValue(info.FieldType, loadKeyName); 调用的函数返回值 可是 object 啊!
而此时 info(字段) 的类型是 System.Int32,那么 SetValue()这个函数的作用不就是 把 LoadValue(info.FieldType, loadKeyName); 得到的值,赋给当前 info(字段) 吗!!
F12 我们进入 SetValue(),可以看到 的确得到的值是 一个object
**public void SetValue(object obj, object value);**
那么问题就来了!
这不是就是在用一个 System.int32 来装一个 object 类型的值吗?
不就违背了 里氏替换 原则吗?
最后啊!
直接搬出 大模型 问了一下,我得到了如下结果
FieldInfo.SetValue方法接受一个对象实例和一个值来设置该实例上指定字段的值。当调用这个方法时,如果传递给它的值的类型是目标字段的兼容类型(或者是该类型的包装类型),那么值会被正确地解箱(unboxing)并赋值给字段。解箱是装箱的反向操作,它从一个对象类型提取出值类型。
在 C# 中,当将一个值类型的对象赋给一个接收 object 类型的参数时,会发生装箱操作,即将值类型包装为引用类型。这意味着 info.SetValue(date, o) 中的 o(类型为 object)会自动进行装箱操作,将 int 类型的值包装为 object 类型的引用。
Change text当调用 info.SetValue(date, o) 时,SetValue 方法会根据字段的类型(System.Int32)来进行适当的拆箱操作,将装箱后的 object 类型的值转换回 int 类型,并将其赋给 info 字段。
所以,即使没有显式进行强制类型转换,隐式类型转换和装箱/拆箱操作会在 info.SetValue(date, o) 中 Change text自动发生 ,使得赋值操作正常工作。
看完这段话,我的理解是:人家 SetValue 方法,应该是自动的!
聊天记录