You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity存档系统泛型方法的类型约束问题及解决方案

Unity存档系统泛型约束问题及解决方法

我在Unity开发一套支持数据保存的存档系统时,在泛型逻辑部分遇到了问题:程序加载类型为T的元素时,需要先检查该元素是否存在,存在则加载存档,不存在则通过T类的无参构造函数创建新实例。

核心问题在于:我定义了Savable类作为所有需保存数据类的父类,但不知道如何约束泛型方法的类型参数T,使得T既能被当作Savable类型访问其成员(比如Name属性),同时方法返回的对象仍保持T类型。我曾尝试直接使用T类并调用带参构造函数,但没有效果。

原问题代码

SaveManager 类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public static class SaveManager
{
    public static void SaveFromJson<T>(T data, string name, string path)
    {
        path = Application.persistentDataPath + path;

        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        path = path + name + ".txt";

        string json = JsonUtility.ToJson(data, true);

        File.WriteAllText(path, json);
    }

    public static T LoadFromJson<T>(string name, string path) where T : new()
    {
        path = Application.persistentDataPath + path + name + ".txt";

        Savable data = new T();

        if (Directory.Exists(path))
        {
            string json = File.ReadAllText(path);

            data = JsonUtility.FromJson<T>(json);
        }
        else
        {
            data.Name = name;
        }

        return data;
    }
}

Savable 父类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Savable
{
    public string Name;
}

解决方案

只需在泛型方法的new()约束前添加Savable类型约束即可,这样能同时满足三个要求:

  • 约束T必须是Savable的子类,可直接访问Savable的成员(如Name)
  • 保留new()约束,确保T具备无参构造函数,能够创建新实例
  • 返回值仍为T类型,无需额外类型转换

修改后的代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public static class SaveManager
{
    public static void SaveFromJson<T>(T data, string name, string path)
    {
        path = Application.persistentDataPath + path;

        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        path = path + name + ".txt";

        string json = JsonUtility.ToJson(data, true);

        File.WriteAllText(path, json);
    }

    public static T LoadFromJson<T>(string name, string path) where T : Savable, new()
    {
        path = Application.persistentDataPath + path + name + ".txt";

        T data = new T();

        if (Directory.Exists(path))
        {
            string json = File.ReadAllText(path);

            data = JsonUtility.FromJson<T>(json);
        }
        else
        {
            data.Name = name;
        }

        return data;
    }
}

内容的提问来源于stack exchange,提问作者Singul4r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 13:30:24