繁体   English   中英

使用接口作为泛型方法的类型参数

[英]Using an interface as type parameter to generic method

我在Unity3d游戏工作使用C#,和我们有很多的情况下,我们需要访问特定成员(比如, int health一)的GameObject 我们使用以下代码执行此操作:

GameObject obj;
if(obj.GetComponent<Player>() != null) {
    obj.GetComponent<Player>().health--;
}
else if(obj.GetComponent<Robot>() != null) {
    obj.GetComponent<Robot>().health--;
}
// more painful code

我想做的是让所有这些类都实现IHealth类的接口,然后执行obj.GetComponent<IHealth>().health--; . 不过,这可能吗? 我环顾四周,似乎不能将接口用作类型参数。

事实证明,这并不容易,而且可能不是一个好主意。 问题是GetComponent<T>期望类型参数T派生自Component (当然,Unity 没有记录这一点)。 我需要让RobotPlayer等都从一个抽象类派生,该抽象类本身继承自Component (通过MonoBehaviour ),并包含有关健康和其他领域的信息。 我怀疑这是否值得; 它可能会在其他地方导致同样多的混乱代码。

正如 SLaks 所指出的,接口作为泛型类型参数是完全可以接受的。 如果您的问题是通过接口访问字段,那么我建议只需将您的字段更改为属性。 如果由于某种原因您绝对必须保留该字段,只需提供一个隐式实现该接口的包装属性。 如果问题是字段和属性具有完全相同的名称(包括大小写),则可以显式实现该接口:

public interface IHealth { int Health { get; set; } }

// Change to a property
public class Ogre : IHealth { public int Health { get; set; } }

// Casing is different, so interface can be implemented implicitly
public class Player : IHealth {
    int health;
    public int Health { get { return health; } set { health = value; } }
}

// Name collision with Pascal casing, so implement explicitly
public class Robot : IHealth {
    int Health;
    int IHealth.Health { get { return Health; } set { Health = value; } }
}

// Later
GameObject obj;
var o = obj.GetComponent<IHealth>();
if (o != null) o.Health--;

我认为您有一个基本的设计问题,因为您的消费代码需要了解每种类型。 如果您不考虑类型而采取相同的操作,那么只需使用好的 ol' 多态性:

public class Player: IHealth {}

public class Robot: IHealth {}

从 GetComponent 中删除泛型参数并让它返回一个 IHealth 对象,而不是一堆if语句:

public IHealth GetComponent()
{
    // return IHealth object here
}

在您的调用代码中:

obj.GetComponent().DecreaseHealth();

为什么不只拥有一个组件Health 然后将它附加到你的游戏对象,在任何需要健康的脚本上有一个RequiresComponent注释,然后通过GetComponent<Health>();获取它GetComponent<Health>(); (将其缓存在私有变量中的相同对象脚本中)

如果您有多个始终在一起的“统计数据”,则可以使其更容易,例如

public class Status : MonoBehaviour
{
    public float health;
    public float armor;
}

我团结一致地发现,这是一个令人惊讶的常见“问题”。 不确定这是否是一个问题,因为这种想法确实可以帮助解决一些问题......

暂无
暂无

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

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