[英]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 没有记录这一点)。 我需要让Robot
、 Player
等都从一个抽象类派生,该抽象类本身继承自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.