C# 在公共变量中保存开关盒中的对象

C# 在公共变量中保存开关盒中的对象,c#,variables,inheritance,switch-statement,C#,Variables,Inheritance,Switch Statement,我必须编写一个程序,在这个程序中,我可以使用开关盒选择一种武器,但具体武器的实现方式各不相同(例如,格洛克手枪听起来不同,其弹夹大小也不同于沙漠之鹰) 我如何确保每种武器的射击和重新装填方法都是正在运行的方法?例如,如何将选择的枪保存为变量,以便我可以运行类似于currentWearm.Shoot,这将确保它是当前选择的武器,而不是pistol.Shoot()方法?您需要同时使用继承和多态性,以便在对基类类型的对象调用方法时(或接口),实际上将调用派生类的虚方法 这里是我对同一问题的最佳答案之一

我必须编写一个程序,在这个程序中,我可以使用开关盒选择一种武器,但具体武器的实现方式各不相同(例如,格洛克手枪听起来不同,其弹夹大小也不同于沙漠之鹰)


我如何确保每种武器的射击和重新装填方法都是正在运行的方法?例如,如何将选择的枪保存为变量,以便我可以运行类似于
currentWearm.Shoot
,这将确保它是当前选择的武器,而不是
pistol.Shoot()
方法?

您需要同时使用继承和多态性,以便在对基类类型的对象调用方法时(或接口),实际上将调用派生类的虚方法

这里是我对同一问题的最佳答案之一:

我猜Glock实现了IPistol接口,对吗?如果是这样的话,你可以这样做

Console.WriteLine("Please, choose your weapon. \n1: Glock 18 \n2:");

switch (choice)
{
    case 1:
        Glock18 glock18 = new Glock18() ;
        break;
}


 Console.WriteLine("Let's shoot. Press space to fire and 'r' to reload. ('q' to quit) \n");

while (true)
{
    ConsoleKeyInfo input = Console.ReadKey(true);
    if (char.IsWhiteSpace(input.KeyChar))
    {
        pistol.Shoot();
    }
}
您可以尝试使用为您的代码提供
武器

创建一个所有武器基地的界面,界面中有一个方法
shot

IPistol pistol;  

Console.WriteLine("Please, choose your weapon. \n1: Glock 18 \n2:");
            switch (choice)
            {
                case 1:
                    pistol = new Glock18() ;
                    break;
                case 2:
                    pistol = new WaltherP99() ;
                    break;
                default:
                    pistol = new BasicGun() ;
                    break;
            }


            Console.WriteLine("Let's shoot. Press space to fire and 'r' to reload. ('q' to quit) \n");

            while (true)
            {
                ConsoleKeyInfo input = Console.ReadKey(true);
                if (char.IsWhiteSpace(input.KeyChar))
                {
                    pistol.Shoot();
                }
然后让
Glock18
或其他类型的武器实现
IWeapon
接口,并在方法中建立自己的逻辑

public interface IWeapon {
    void Shoot();
}
武器工厂
提供武器生产代码创建

public class Glock18 : IWeapon
{
    public void Shoot()
    {
        // Do Glock18 shoot thing
    }
}
然后你可以通过
武器工厂
类获得武器,通过你想要的武器模式

public class WeaponFactory {
    public static IWeapon GetWeapon(int choice)
    {
        IWeapon weapon = null;
        switch (choice)
        {
            case 1:
                weapon = new Glock18();
                break;
        }
        return weapon;
    }
}
我如何确保每种武器的射击和重新装载方法都是正在运行的方法?即,如何将所选枪保存为变量,以便我可以运行类似于
currentwearm.shoot
,这将确保它是当前所选的武器,而不是
pistol.shoot()
方法

在switch语句中,将您创建的武器分配给一个表示任何武器的变量。该变量必须是您接口的类型

因此,第1步,为你所有的武器(枪)创建一个界面。它们都有相似的操作,但在发射时会有所不同。这是,你可以通过或

然后是各种类(实现取决于您):

然后在“操作”代码中,声明属于接口类型的变量。这是所选的武器

class BasicPistol : IWeapon { ... }
class Glock18: IWeapon { ... }
class GiganticLaserBlaster: IWeapon { ... }
switch
语句中指定该变量(不过,正如其他一些答案所说,工厂会更好)

然后用你的武器做任何你想做的事。你知道这是正确的方法,因为你有正确的武器

switch (choice)
{
    case 1:
        chosenWeapon = new Glock18() ;
        break;
    case 2:
        chosenWeapon = new GiganticLaserBlaster() ;
        break;
    ...
    default:
        chosenWeapon = new BasicPistol();
        break
}

您的代码是否不完整,或者这是实际代码?因为使用提供的代码无法从用户处获得任何输入。请尝试以下操作:

while (true)
{
    ConsoleKeyInfo input = Console.ReadKey(true);
    if (char.IsWhiteSpace(input.KeyChar))
    {
        if (chosenWeapon.HasAmmo)
            chosenWeapon.Shoot();
        else
           chosenWeapon.MakeClickSound();
    }
    else if (input.KeyChar == 'r')
        chosenWeapon.Reload();
}

你需要你的武器来实现某种共享功能,要么通过基类,要么通过实现接口。基类在这里可能更符合逻辑。然后在基类中实现共享功能你刚才描述的注释者是对的;通过子类型继承的整个要点ng是为了避免必须打开对象的类型,而是将逻辑放在对象本身中。但也就是说,我认为这些注释并没有解决您的问题,这是我不太理解的。您在问一些关于switch语句的问题;您能更清楚些吗?我注意到在您的程序片段中有一个代码
pistol
未初始化的路径;您可能希望将其设置为null或使用默认大小写。谢谢。我做了一个小编辑。此代码远非完美。它只是让OP了解多态性的工作原理。我尝试过这种方法,但CurrentBlarm.Shoot()在开关中找不到我分配给它的Glock18值。当尝试调用该方法时,当鼠标悬停在“CurrentBear”上时,它会显示“使用未分配的局部变量”。请发布整个方法好吗?
IWeapon chosenWeapon;
switch (choice)
{
    case 1:
        chosenWeapon = new Glock18() ;
        break;
    case 2:
        chosenWeapon = new GiganticLaserBlaster() ;
        break;
    ...
    default:
        chosenWeapon = new BasicPistol();
        break
}
while (true)
{
    ConsoleKeyInfo input = Console.ReadKey(true);
    if (char.IsWhiteSpace(input.KeyChar))
    {
        if (chosenWeapon.HasAmmo)
            chosenWeapon.Shoot();
        else
           chosenWeapon.MakeClickSound();
    }
    else if (input.KeyChar == 'r')
        chosenWeapon.Reload();
}
Console.WriteLine("Please, choose your weapon. \n1: Glock 18 \n2:");
string choice = Console.ReadLine();
switch (choice)
{
    case 1:
        Glock18 glock18 = new Glock18() ;
        break;
}