C# 我可以使用主类对象作为参数来查找子类对象吗?
我对编码还是有点陌生,所以我想知道这是否/如何工作C# 我可以使用主类对象作为参数来查找子类对象吗?,c#,class,casting,type-conversion,C#,Class,Casting,Type Conversion,我对编码还是有点陌生,所以我想知道这是否/如何工作 //a class with armor with subclasses to say what part of the body it go's public class Armor { //stuff that applies to all armor } public class HeadArmor : Armor { //stuff for HeadPieces only } public class
//a class with armor with subclasses to say what part of the body it go's
public class Armor
{
//stuff that applies to all armor
}
public class HeadArmor : Armor
{
//stuff for HeadPieces only
}
public class ChestArmor : Armor
{
}
//etc
//the class that stores what armor is equiped
public class MainCharacterEquipment
{
//the class of my maincharacter
public MainCharacter HeroEquipment { get; set; }
public HeadArmor HeadSlot { get; set; }
public ChestArmor ChestSlot { get; set; }
//etc
//a constructor that sets all to null
public void EquipArmor(Armor armor)
{
if (armor is HeadArmor)
{
HeadSlot = armor; //compile error
}
if (armor is ChestArmor)
{
ChestSlot = armor; //compile error -> Missing a cast?
}
//etc
}
}
如果我这样做,它会问我是否错过了演员阵容。
从本论坛的阅读来看,子类似乎是mainclass的一种类型
但不是相反
为了解决这个问题,我可以为装甲的每个子类创建一个方法。
我将使用(HeadArmor HeadArmor),(ChestArmor ChestArmor)等,而不是使用(Armor Armor)作为参数。。。
但这似乎很乏味。
我还读到typeof()和is之间有区别,但我也不太明白这一点。
我最好将对象盔甲转换为它的子类。当然,if函数应该检查它是否已经是子类(如果有意义的话)
ps:实际上没有装甲物体的实例。只实例化子类的对象。(如果有关系)您需要在执行作业时指定相同的强制转换。一旦初始检查通过,编译器就不会通过
if
语句携带信息
在代码中:
if (armor is HeadArmor) // The compiler verifies this is HeadArmor
{
// The compiler does not carry the information forward.
// It has no way of knowing, on this line, that armor is still HeadArmor.
// For all it knows, armor could be ChestArmor which would be invalid.
HeadArmor = armor;
}
要修复此错误,您需要按如下方式更新代码:
if (armor is HeadArmor)
{
HeadArmor = (HeadArmor)armor; // Lets the compiler know this is HeadArmor.
}
另一种选择是使用as
尝试并找出正确的选择
var headArmor = armor as HeadArmor;
if (headArmor != null)
{
HeadArmor = headArmor;
}
执行赋值时,需要指定相同的强制转换。一旦初始检查通过,编译器就不会通过
if
语句携带信息
在代码中:
if (armor is HeadArmor) // The compiler verifies this is HeadArmor
{
// The compiler does not carry the information forward.
// It has no way of knowing, on this line, that armor is still HeadArmor.
// For all it knows, armor could be ChestArmor which would be invalid.
HeadArmor = armor;
}
要修复此错误,您需要按如下方式更新代码:
if (armor is HeadArmor)
{
HeadArmor = (HeadArmor)armor; // Lets the compiler know this is HeadArmor.
}
另一种选择是使用as
尝试并找出正确的选择
var headArmor = armor as HeadArmor;
if (headArmor != null)
{
HeadArmor = headArmor;
}
我建议采用访客模式:
public abstract class Armor
{
public abstract void Equip( MainCharacterEquipment mce );
}
public class HeadArmor : Armor
{
public override void Equip( MainCharacterEquipment mce )
{
mce.HeadSlot=this;
}
}
public class ChestArmor : Armor
{
public override void Equip( MainCharacterEquipment mce )
{
mce.ChestSlot=this;
}
}
那么您的MainCharacterEquipment代码可以归结为:
public void EquipArmor(Armor armor)
{
armor.Equip(this);
}
这就去掉了“if-else”,如果你后来选择添加更多类型的护甲和插槽,你就不需要再碰这些代码了。只需添加另一个XXXXArmor类,它就会转到正确的位置。我建议使用访客模式:
public abstract class Armor
{
public abstract void Equip( MainCharacterEquipment mce );
}
public class HeadArmor : Armor
{
public override void Equip( MainCharacterEquipment mce )
{
mce.HeadSlot=this;
}
}
public class ChestArmor : Armor
{
public override void Equip( MainCharacterEquipment mce )
{
mce.ChestSlot=this;
}
}
那么您的MainCharacterEquipment代码可以归结为:
public void EquipArmor(Armor armor)
{
armor.Equip(this);
}
这就去掉了“if-else”,如果你后来选择添加更多类型的护甲和插槽,你就不需要再碰这些代码了。只需添加另一个XXXXArmor类,它将进入正确的位置。尝试
如果(armor是HeadArmor hArmor){HeadSlot=hArmor;}…
如果类型匹配,这也将执行强制转换。当然,有更多的解决方案。。。但是从简单开始。@Korosevar你在为Unity开发这些东西吗?如果是这样的话,模式匹配将不起作用@Fildor i get error:hArmor在当前上下文中不存在为什么不将HeadSlot和ChestSlot都设置为Armor类型?那就是多态性发光的时候。那是哪个站台。Net框架4.7。净核心?团结。。。这可能会排除一些解决方案…请尝试如果(armor是HeadArmor hArmor){HeadSlot=hArmor;}…
如果类型匹配,也会执行强制转换。当然,有更多的解决方案。。。但是从简单开始。@Korosevar你在为Unity开发这些东西吗?如果是这样的话,模式匹配将不起作用@Fildor i get error:hArmor在当前上下文中不存在为什么不将HeadSlot和ChestSlot都设置为Armor类型?那就是多态性发光的时候。那是哪个站台。Net框架4.7。净核心?团结。。。这可能排除了一些解决方案…解决了它。看起来真的很干净。(头甲)盔甲是铸的吗?是的,没错。(HeadArmor)armor告诉代码将该armor解释为HeadArmor,即使编译器知道它是一种armor类型。看起来真的很干净。(头甲)盔甲是铸的吗?是的,没错。(HeadArmor)armor告诉代码将该armor解释为HeadArmor,即使编译器知道它的类型是armor。是否可能必须在抽象类中使用公共虚拟void?我得到“不能声明一个实体,因为它是抽象的”,在类似的情况下,有可能在抽象类中使用公共虚空吗?在类似的情况下,我得到“不能声明一个实体,因为它是抽象的”