【问题标题】:InvalidCastException: Specified cast is not valid in UnityInvalidCastException:指定的强制转换在 Unity 中无效
【发布时间】:2019-11-15 09:41:35
【问题描述】:

我从 Car 类型生成 JSON 表示,然后从该 json 创建一个 System.Object。当我尝试将该对象显式转换为 Car 类型时,它会显示错误“InvalidCastException:指定的转换无效”。谁能给我解释一下原因?

using System;
using UnityEngine;
[Serializable]
class Car
{
    public string type;
}
public class Test : MonoBehaviour
{   
    void Start()
    {
        Car car = new Car();
        car.type = "BMW";

        string json = JsonUtility.ToJson(car);
        System.Object @object = JsonUtility.FromJson<System.Object>(json);
        car = (Car)@object;
        Debug.Log(car.type);
    }
}

【问题讨论】:

  • 你正在反序列化到object,它不能转换为Car。为什么不直接反序列化到Car?像这样:var car = JsonUtility.FromJson&lt;Car&gt;(json);
  • 我试图了解这个错误的深层原因。
  • 原因是“你没有创建 Car 的实例,所以你不能强制转换为 Car”。

标签: c# json unity3d


【解决方案1】:

您在那里尝试执行的操作称为 Down/UpCasting。

在c#中object是所有其他类型的父类。因此,您可以简单地将继承的类型(例如在本例中的 Car 分配给 object)变量。这称为Upcast

然后,当尝试从更通用的类型转换为更具体的类型时(在您的情况下,objectCar 这称为 Downcast

您只能将object(顺便说一句,这只是System.Object 的类型关键字和别名)直接向下转换为Car 如果以前这实际上Car参考 例如

Car car = new Car();
car.type = "BMW";

//string json = JsonUtility.ToJson(car);
//System.Object @object = JsonUtility.FromJson<System.Object>(json);
object @object = car;
car = (Car)@object;
Debug.Log(car.type);

从现在开始可以工作 @object 实际上仍然保存 Car 的信息,但装箱object


你不能用

System.Object @object = JsonUtility.FromJson<System.Object>(json);

System.Object 不可(反)序列化,并且在此处作为目标类型绝对没有意义,因为类型 object 也没有关于您要反序列化的字段的信息。你想要的是Car 而不是object

所以你可以使用的是

// Here the Car reference returned by FromJson is BOXED into object
System.Object @object = JsonUtility.FromJson<Car>(json);
// Since @object is still a boxed Car value it is now UNBOXED from object to Car
car = (Car)@object;

但是,为什么整个演员阵容根本?你真的很想用

car = JsonUtility.FromJson<Car>(json);

【讨论】:

  • 这里的术语有误。 装箱是将值类型包装到对象中的过程,而拆箱是它的逆过程。 (参见 C# 编程指南中的 Boxing and Unboxing。)这里,Car 不是值类型;它是一个引用类型。换句话说,它已经是一个对象。因此,您在示例中实际所做的只是 UpcastingDowncasting。但是你的主要观点仍然存在——如果对象不是真正的Car,你不能将对象向下转换为Car
  • (框:intvs Integer
  • @BrianRogers 感谢您澄清这一点。在我看到的拆箱自动翻译版本中,它仅适用于值类型并不清楚。由于该示例仅在 objectint 之间,因此我认为它对于其他类型和类也将被称为相同。
猜你喜欢
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 2021-02-11
  • 2019-11-02
  • 1970-01-01
  • 2018-05-27
  • 2014-07-30
  • 2012-06-12
相关资源
最近更新 更多