我的问题是如何从我的列表存储基础项访问派生类函数和方法。我可以通过创建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...);
有效。
答案 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
}
}
您不必一次又一次地进行转换。