从BaseClass转换为DerivedClass(存储在列表中)

时间:2014-05-29 00:21:34

标签: c# generics

我的问题是如何从我的列表存储基础项访问派生类函数和方法。我可以通过创建Item的新实例并使用as关键字来完成此操作。但是,每次我想要转换它时都必须创建一个很好的实例。

首先是将要存储在List中的通用类。从这个课程中会有很多遗产,现在,我只是在使用oner。

public class Item
{
    public string Name { get; protected set; }

    protected Item() {}

    public Item(string name)
    {
        Name = name;
    }
}

项目的变体(也存储在列表中)

public class Weapon : Item
{
    public int MinDmg { get; protected set; }

    public Weapon(string name, int mindmg)
    {
        Name = name;
        MinDmg = mindmg;
    }
}

主程序

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        List<Item> Items = new List<Item>();
        Items.Add(new Item("Mushroom"));
        Items.Add(new Weapon("Dagger", 2, 4));

        foreach (Item item in Items)
        {
            Console.WriteLine(item.Name + "\n");
            if (item.GetType() == typeof(Weapon))
            {
                Console.WriteLine("Damage: " + (Weapon)item.MinDmg + " - " + (Weapon)item.MaxDmg + "\n"); // Error
            }
        }
    }
}

错误:错误似乎是我的演员失败了。由于错误状态&#34; Item不包含MinDmg的定义而且没有...&#34;

如果我按照以下方式这样做:

Weapon w = (Weapon)item;
Console.WriteLine ("Damage: " + w.MinDmg...);

有效。

3 个答案:

答案 0 :(得分:2)

您应该说如下,因为qualification x.y的优先级高于casting (T)x

所以当你说(Weapon)item.MinDmg时,它首先尝试在Item中找到一个名为mindmg的属性,该属性不存在。你应该像((Weapon)item).MinDmg

那样试试
Console.WriteLine("Damage: " + ((Weapon)item).MinDmg

答案 1 :(得分:1)

没有办法进行演员表演。以这种方式看待它。如果你有另一个继承自Item但没有MinDmg属性的类,它将以完全不同的方式失败。

您可能想要做的是像这样过滤列表:

var weapons = Items.OfType<Weapon>();

这会为您提供Weapon个对象的列表。

进一步要注意。我可能也会将MinDmg属性提取到它自己的界面中。这样你可以有这样的东西:

public interface IDamage
{
    public int MinDmg { get; get; }
}

public class Weapon : Item, IDamage
{
    //Stuff in here to calculate damage perhaps
}

public class Spell : IDamage
{
    //Spells can also cause damage
}

现在你可以通过这条线获得所有造成伤害的物品:

var damagingItems = Items.OfType<IDamage>();

答案 2 :(得分:0)

为了安全起见,您可以这样做:

As和是用于此目的的好关键字。

 if (item is Weapon)
            {
                  Weapon w = item as Weapon; 
                  if ( w != null ) { 
                Console.WriteLine("Damage: " + w.MinDmg + " - " + w.MaxDmg + "\n"); // Error
            }
}

您不必一次又一次地进行转换。