Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以使用主类对象作为参数来查找子类对象吗?_C#_Class_Casting_Type Conversion - Fatal编程技术网

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?我得到“不能声明一个实体,因为它是抽象的”,在类似的情况下,有可能在抽象类中使用公共虚空吗?在类似的情况下,我得到“不能声明一个实体,因为它是抽象的”