首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当B从A继承时,list<A> = list<B>?

当B从A继承时,list<A> = list<B>?
EN

Stack Overflow用户
提问于 2013-07-13 00:41:51
回答 2查看 175关注 0票数 0

基本上我有

继承自Projectile类的BallisticProjectile类。现在我可以这样做了

代码语言:javascript
复制
Projectile A;
BallisticProjectile B;

Projectile myfunction()
{
    return B;
}

然后返回B作为投射物。

但我做不到

代码语言:javascript
复制
list<Projectile> myfunction()
{
    return B;
}

我不确定该如何克服这一点。

我是否需要一个包装类来包装它,这样我就可以像这样

代码语言:javascript
复制
ProjectileList
{
    list<projectile> Projectiles;
}

BallisticProjectiles : Projectile
{
    list<ballisticprojectile> Projectiles;
}

真实代码(来自unity游戏引擎)

代码语言:javascript
复制
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;
        }
    }
}

其他脚本

代码语言:javascript
复制
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;
        }
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-13 01:20:07

List<BallisticProjectile>不能用作List<Projectile>。理解原因的一种简单方法是,您可以将new Projectile()添加到List<Projectile>中,这在List<BallisticProjectile>中没有任何意义。

此方法允许您以通用方式设置投射类型,并可能解决您的问题(与p.s.w.g建议的相同):

代码语言:javascript
复制
public class ProjectileList<T> where T : Projectile
{
    List<T> Projectiles;
}

更新:在您的示例中,可能如下所示:

代码语言:javascript
复制
public abstract class Weapon<T> : MonoBehaviour where T : Projectile {
    public virtual IList<T> Projectiles { get; set; }
}

然后:

代码语言:javascript
复制
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的方法。

票数 0
EN

Stack Overflow用户

发布于 2013-07-13 00:49:52

在C# 4中,如果B继承自A,则可以将IEnumerable<B>转换为IEnumerable<A>。这是可能的,因为IEnumerable<T>与T是协变的(但List<T>与T是逆变的)。因此,您可以使用IEnumerable<>来代替List<>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17619824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档