c# - Unity/C#:按值进行类特化(相当于 C++ std::array<int>)

标签 c# c++ templates generics unity3d

我有一个问题,我知道如何在 C++ 中解决,但我不知道它在 C# 中如何工作。这是 C# 中的示例代码:

public class TowerTile<ScriptType, SpriteName> : Tile where ScriptType : MonoBehaviour {
    private void Awake() {
        gameObject = new GameObject();
        gameObject.AddComponent<ScriptType>();
        colliderType = Tile.ColliderType.None;
        sprite = GameManager.shared.sprites[SpriteName];
    }
}

SpriteName该示例中的类型应为字符串,因此我可以在 operator[] 中使用它在 Dictionary<string, Sprite> sprites .

以下是我用 C++ 编写的方法:

template <typename ScriptType, typename SpriteRef = std::string> 
class TowerTile : public Tile {
    private void Awake() {
        gameObject = new GameObject();
        gameObject.AddComponent<ScriptType>();
        colliderType = Tile.ColliderType.None;
        sprite = GameManager.shared.sprites[SpriteRef];
    }
}

如何在 C# 中实现此目的?我无法将字符串作为构造函数参数传递,因为这些 Tile 对象是用 ScriptableObject.CreateInstance<T>() 实例化的,它不能传递任何构造函数参数。

最佳答案

为了让问题和答案更清楚,我想从示例中模板化这个类,因为它在 Unity 中用 ScriptableObject.CreateInstance<T>() 实例化的方式不允许构造函数参数。即使在 C# 中可以按值进行特化(这不是),它也无济于事,因为实例化方法无论如何都无法创建泛型类型(为什么是 Unity?)。所以我使用的解决方案是一个带有模板化方法的工厂,该方法返回基类“Tile”。

public class TileFactory {
    private TileFactory() {}

    public static Tile CreateInstance<ScriptType>(string spriteName) where ScriptType : DefaultAI {
        var tile = ScriptableObject.CreateInstance<TowerTile>();
        tile.sprite = GameManager.shared.sprites[spriteName];
        tile.gameObject.name = spriteName;
        tile.gameObject.GetOrAddComponent<ScriptType>();
        return tile;
    }
}

所讨论示例的变化是:

  • 无法通过spriteName的问题进入ScriptableObject.CreateInstance<T>()通过将此方法包装在我自己的工厂方法中来解决。
  • ScriptableObject.CreateInstance<T>()使用非通用类型调用,并且仅在将通用类型脚本添加到对象之后。
  • 返回的实例也是一种非泛型类型,因为某些原因,Unity 似乎存在一些问题。
  • ScriptType现在应该是基地 DefaultAI这是基地 MonoBehaviour (与本答案的目的无关)。

另一种选择是使用 Buidler但是因为我只需要传递 1 个必需的参数,builder 就没有多大意义了。在其他一些情况下,这将是更好的解决方案。

p.s.感谢 Furkan Kambay 提供相关资源帮助解决此问题

关于c# - Unity/C#:按值进行类特化(相当于 C++ std::array<int>),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48366181/

相关文章:

c# - 如果 Int32 只是 int 的别名,那么 Int32 类如何使用 int?

c# - Veracode 对于 C# 中的公共(public)字符串属性抛出 "Technology-Specific Input Validation Problems (CWE ID 100)"

c++ - CUDA __host__ __device__ 变量

c++ - 到底应该如何使用 declttype 来推断函数的返回类型,该函数返回一个在模板上实例化的类实例

c++ - 如何让 `static_assert` 打印失败时得到的值?

c# - C#中级联删除异常的处理方法

c# - 有没有办法确定我在 foreach 循环中的哪一行?

c++ - 如何在 DLL(动态链接库)中运行 MPI

c++ - 如何从运算符函数返回动态对象?

c++ - 在模板中,如果从属名称是函数,则调用它