基本上我有
继承自BallisticProjectile
类的 Projectile
类。现在我可以做到这一点
Projectile A;
BallisticProjectile B;
Projectile myfunction()
{
return B;
}
并将B作为射弹返回。
但我做不到
list<Projectile> myfunction()
{
return B;
}
我不知道如何克服这一点。
我是否需要一个包装类,所以我喜欢
ProjectileList
{
list<projectile> Projectiles;
}
BallisticProjectiles : Projectile
{
list<ballisticprojectile> Projectiles;
}
真实代码(来自统一游戏引擎)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public abstract class Weapon : MonoBehaviour {
IEnumerable<Projectile> _Projectile;
public virtual IEnumerable<Projectile> projectile
{
get
{
return _Projectile;
}
set
{
_Projectile = value;
}
}
}
其他剧本
public override IEnumerable<BallisticProjectile> projectile {
get {
if(_BallisticProjectile == null)
Debug.Log("ERROR: " + this.gameObject.name + " NO PROJECTILE");
return _BallisticProjectile;
}
set {
if(value is IEnumerable<BallisticProjectile>)
{
_BallisticProjectile = value as IEnumerable<BallisticProjectile>;
base.projectile = _BallisticProjectile;
}
}
}
答案 0 :(得分:1)
在C#4中,如果B从A继承,则可以将IEnumerable<B>
转换为IEnumerable<A>
。这是可能的,因为IEnumerable<T>
与T协变(但List<T>
是逆变的T)。所以你可以使用IEnumerable&lt;&gt;而不是列表&lt;&gt;
答案 1 :(得分:0)
List<BallisticProjectile>
不能用作List<Projectile>
。一种简单的方法可以查看为什么您可以将new Projectile()
添加到List<Projectile>
,这对于List<BallisticProjectile>
没有任何意义。
此方法允许您以通用方式设置射弹类型,并可以解决您的问题(与建议的p.s.w.g相同):
public class ProjectileList<T> where T : Projectile
{
List<T> Projectiles;
}
在您的情况下更新,可能如下所示:
public abstract class Weapon<T> : MonoBehaviour where T : Projectile {
public virtual IList<T> Projectiles { get; set; }
}
然后:
public class Crossbow : Weapon<BallisticProjectile> {
// if you needed to override the implementation, you'd start with this:
// public override IList<BallisticProjectile> Projectiles { get { } set { } }
}
这里的问题是,当您覆盖属性时,C#不允许您更改属性(或其他成员)的类型。类型是否以某种方式兼容并不重要,您必须使用相同的类型声明它。通过这种方式,泛型是一种使虚拟属性更改为BallisticProperty
的方法。