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

Unity中C#泛型类型实例化及泛型数组扩容初始化问题咨询

嘿,我来帮你解决Unity C#里这两个泛型相关的问题!下面分两部分给你讲清楚:

一、泛型类型的实例化

在C#里实例化泛型类型,核心是要确保你能创建T的实例,分两种常见场景:

1. 泛型类型有默认无参构造函数

这种情况最简单,只需要给泛型添加where T : new()约束,就能直接用new T()创建实例。比如在Unity的MonoBehaviour里写个泛型工具类:

public class GenericSpawner<T> where T : new()
{
    public T SpawnInstance()
    {
        // 直接创建T的实例
        T instance = new T();
        
        // 如果是Unity的Component,还可以附加到GameObject上
        if (typeof(Component).IsAssignableFrom(typeof(T)))
        {
            GameObject obj = new GameObject(typeof(T).Name);
            return obj.AddComponent<T>();
        }
        
        return instance;
    }
}

这个约束会强制T必须有公开的无参构造函数,编译器才允许你用new T()。

2. 泛型类型没有默认构造函数(需要参数)

如果你的T必须带参数构造,就不能用new T()了,这时候可以用两种方式:

  • 使用Activator.CreateInstance:通过反射创建实例,能传递构造参数,但性能略低(如果不是高频调用完全没问题):
public T SpawnInstanceWithParams(params object[] args)
{
    return (T)Activator.CreateInstance(typeof(T), args);
}
// 调用示例:SpawnInstanceWithParams("Player", 100);
  • 传递工厂方法(更推荐):用Func<T>让外部传入实例创建逻辑,既灵活又避免反射开销:
public T SpawnInstance(Func<T> factory)
{
    return factory();
}
// 调用示例:SpawnInstance(() => new PlayerCharacter("Hero", 100));
二、泛型数组扩容与元素初始化问题

C#数组是固定大小的,所谓“扩容”其实是创建一个更大的新数组,把旧数组元素复制过去,再处理新位置的元素初始化——这也是你遇到问题的核心:新元素默认是default(T)(引用类型为null,值类型为默认值比如0、false),需要手动初始化。

1. 基础扩容方案(带默认构造的T)

同样先加where T : new()约束,确保能创建T的实例:

public static T[] ResizeArray<T>(T[] oldArray, int newSize) where T : new()
{
    if (newSize <= oldArray.Length)
        return oldArray; // 不需要扩容直接返回
    
    T[] newArray = new T[newSize];
    // 复制旧数组元素到新数组
    Array.Copy(oldArray, newArray, oldArray.Length);
    
    // 初始化新增的元素
    for (int i = oldArray.Length; i < newSize; i++)
    {
        newArray[i] = new T();
    }
    
    return newArray;
}
// 调用示例:myArray = ResizeArray(myArray, myArray.Length + 5);

2. 自定义初始化的扩容方案(支持带参数构造)

如果T需要自定义初始化(比如带参数、或者值类型要设非默认值),还是用工厂方法传递初始化逻辑:

public static T[] ResizeArray<T>(T[] oldArray, int newSize, Func<T> elementFactory)
{
    if (newSize <= oldArray.Length)
        return oldArray;
    
    T[] newArray = new T[newSize];
    Array.Copy(oldArray, newArray, oldArray.Length);
    
    // 用传入的工厂方法初始化新元素
    for (int i = oldArray.Length; i < newSize; i++)
    {
        newArray[i] = elementFactory();
    }
    
    return newArray;
}
// 调用示例:myPlayerArray = ResizeArray(myPlayerArray, 10, () => new Player("NPC", 50));
// 值类型示例:myIntArray = ResizeArray(myIntArray, 10, () => 100);

小提示

如果在Unity里不是必须用数组,推荐用List<T>,它自带Add()、AddRange()方法,内部会自动扩容,而且你可以用List<T>.Add(elementFactory())来控制元素初始化,比手动操作数组省心多了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:53:42