简体   繁体   English

C#泛型/ Unity3d-如何提供GameObject约束?

[英]C# Generics / Unity3d - how to supply a GameObject constraint?

I'm just learning to use C# Generics and Unity has thrown me a curve ball. 我只是在学习使用C#泛型,而Unity给我扔了一个曲线球。 I have this method into which I intend to be able to pass either a list or an array and return an item of a variable object type (could be GameObject, ParticleSystem etc depending on the array contents): 我打算将这种方法传递给列表或数组,并返回可变对象类型的项(根据数组内容,可以是GameObject,ParticleSystem等),该方法是:

private T RetrieveItem<T>(IList<T> list) where T : Component
{

    for (int i = 0; i < list.Count; i++)
    {

        if (!list[i].GetComponent<GameObject>().activeInHierarchy)
        {
            return list[i];
        }
    }

    return list[0];
}

This compiles fine, but when I try to use it: 这样可以编译,但是当我尝试使用它时:

GameObject obj = RetrieveItem<GameObject>(myListOrArray);

I get the error "The type 'UnityEngine.GameObject' cannot be used as type parameter 'T' in the generic type or method 'J_ObjectPool.RetrieveItem(IList)'. There is no implicit reference conversion from 'UnityEngine.GameObject' to 'UnityEngine.Component'." 我收到错误消息“类型'UnityEngine.GameObject'不能在通用类型或方法'J_ObjectPool.RetrieveItem(IList)'中用作类型参数'T'。没有从'UnityEngine.GameObject'到' UnityEngine.Component”。”

I've tried using Monobehaviour as the constraint and get the same error (can't cast GameObject to Monobehaviour) and I've tried using UnityEngine.Object but get the same error and additionally I can't use the GetComponent method. 我尝试使用Monobehaviour作为约束条件并获得相同的错误(无法将GameObject转换为Monobehaviour),并且我尝试使用UnityEngine.Object但获得相同的错误,而且我无法使用GetComponent方法。 Finally I've tried using GameObject as the constraint but the compiler complains that "GameObject is not a valid constraint". 最后,我尝试使用GameObject作为约束,但是编译器抱怨“ GameObject不是有效的约束”。

Any ideas how I could get this to work? 有什么想法可以使它起作用吗? Thanks. 谢谢。

While list[i].GetComponent<GameObject>() may compile, it will not make sense during runtime. 虽然list[i].GetComponent<GameObject>()可能会编译,但在运行时没有意义。

GetComponent<T>() returns a Component of type T. GameObject is not a Component, so GetComponent<GameObject>() will always return null. GetComponent<T>()返回GetComponent<T>()类型的Component。GameObject不是Component,因此GetComponent<GameObject>()将始终返回null。

GameObjects and Components are two completely seperate things. GameObjects和Components是两个完全独立的事物。 A GameObject is basically a container that contains any number of Components. GameObject基本上是一个包含任意数量的Components的容器。 You can get the GameObject that holds the Component like this: 您可以通过以下方式获取包含组件的GameObject:

Component component = ...;
GameObject containingObject = component.gameObject;

So your code should probably read 因此,您的代码可能应该阅读

private T RetrieveItem<T>(IList<T> list) where T : Component
{
    for (int i = 0; i < list.Count; i++)
    {
        if (!list[i].gameObject.activeInHierarchy)
        {
            return list[i];
        }
    }
    return list[0];
}

You might ask, why GetComponent<T>() does not contrain T to be a Component. 您可能会问,为什么GetComponent<T>()不禁止T成为组件。 That is to allow GetComponent to be used with Interface types, too, which of course can not be derived from Component, while Components can still implement them. 那就是允许GetComponent也可以与Interface类型一起使用,当然不能从Component派生出它,而Components仍然可以实现它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM