Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.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#_Object_Properties_Switch Statement - Fatal编程技术网

C# 使用对象实例切换 编辑

C# 使用对象实例切换 编辑,c#,object,properties,switch-statement,C#,Object,Properties,Switch Statement,下面是一个不同版本的代码,它让我更清楚地了解我要做的事情: class Program { static void Main(string[] args) { RepairCar(Car.Ferrari); } public static void RepairCar(Car BrokenCar) { switch (BrokenCar) { case Car.Ferrari:

下面是一个不同版本的代码,它让我更清楚地了解我要做的事情:

class Program
{
    static void Main(string[] args)
    {
        RepairCar(Car.Ferrari);
    }

    public static void RepairCar(Car BrokenCar)
    {
        switch (BrokenCar)
        {
            case Car.Ferrari:
                Console.WriteLine("${0} of Insurance Needed", CalculateInsurance(BrokenCar));
                // 
                // Repair Algorithm Here
                //
                break;

            case Car.BMW:
                Console.WriteLine("${0} of Insurance Needed", CalculateInsurance(BrokenCar));
                // 
                // Repair Algorithm Here
                //
                break;

            case Car.Audi:
                Console.WriteLine("${0} of Insurance Needed", CalculateInsurance(BrokenCar));
                // 
                // Repair Algorithm Here
                //
                break;

            default:
                Console.WriteLine("${0} of Insurance Needed", CalculateInsurance(BrokenCar));
                // 
                // Repair Algorithm Here
                //
                break;
        }
    }

    public static double CalculateInsurance(Car BrokenCar)
    {
        return (BrokenCar.Price / 10);
    }

}

public class Car
{
    public double Price;
    public int MaxSpeed;
    public int MinSpeed;

    public Car(double Price, int MaxSpeed, int MinSpeed)
    {
        this.Price = Price;
        this.MaxSpeed = MaxSpeed;
        this.MinSpeed = MinSpeed;
    }

    public static Car Ferrari = new Car(100000, 250, 10);
    public static Car Audi = new Car(50000, 120, 30);
    public static Car BMW = new Car(35000, 80, 75);
}
如前所述,这不会编译,因为它不允许我在RepairCar方法中切换BrokenCar。有什么建议吗

原职 我正在尝试创建一个可以存储静态属性的对象,更重要的是,它可以被切换——下面是一个例子-

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(GetMaxSpeed(Car.Ferrari));
        Console.ReadLine();
    }

    public static int GetMaxSpeed(Car ModelType)
    {
        switch (ModelType)
        {
            case Car.Ferrari:
                return Car.Ferrari.MaxSpeed;

            case Car.VW:
                return Car.VW.MaxSpeed;

            case Car.AstonMartin:
                return Car.AstonMartin.MaxSpeed;
        }
    }

    public class Car
    {
        public int MinSpeed;
        public int MaxSpeed;

        public Car(int MinSpeed, int MaxSpeed)
        {
            this.MinSpeed = MinSpeed;
            this.MaxSpeed = MaxSpeed;
        }

        public static Car Ferrari = new Car(30, 240);
        public static Car VW = new Car(10, 50);
        public static Car AstonMartin = new Car(75, 180);
    }

}
有人有什么想法吗

编辑 这个例子描述了一个更大、更复杂的系统。要说明我为什么需要这样做,请参阅以下更新:

    public static void OnCarSale(Car CarSold)
    {
        double LuxuryTax = 75;

        switch (CarSold)
        {
            case Car.Ferrari:
                Console.WriteLine("Total Price: {0}", Car.Ferrari.Price + LuxuryTax);
                break;

            case Car.VW:
                Console.WriteLine("Total Price: {0}", Car.VW);
                break;

            case Car.AstonMartin:
                Console.WriteLine("Total Price: {0}", Car.Ferrari.Price + LuxuryTax);
                break;
        }
    }

这将被此类之外的事件调用。

若要直接回答您的问题,请将ModelType设置为枚举并关闭该值。在下面的示例中,让汽车类型具有名为“Model”的ModelType属性

public enum ModelType
{
    Ferrari = 0,
    AstonMartin = 1
}

public int GetMaxSpeed( Car car )
{
    switch( car.Model )
    {
        case Ferrari:
           return 300;
        case AstonMartin:
           return 250;
        default:
           return 100;
    }
}
但更好的问题是,为什么不使用多态性?您可以将汽车作为基本类型,并从中继承不同的模型。基本车辆类型应具有MaxSpeed属性。无论您从Car继承了哪个子类,都可以引用MaxSpeed来获取该特定模型的属性值。这可能会使示例过于复杂(家庭作业?),但会使代码更加面向对象

public class Car
{
    private int _maxSpeed = 200;
    public int MaxSpeed
    {
        get { return _maxSpeed; }
        protected set { _maxSpeed = value; }
    }
}

public class Ferrari : Car
{
    public Ferrari()
    {
        // Constructor 
        this.MaxSpeed = 250;
    }
}

// client code
public void DoStuff()
{
   Car ferrari = new Ferrari();
   Console.WriteLine( ferrari.MaxSpeed );
}
如果你想有一个车库类的汽车清单,它会像下面的东西。请记住,这是非常粗糙的代码,但它向您展示了我在评论中所说的内容

public class Garage
{
    private List<Car> Cars { get; set; }

    public Garage()
    {
       this.LoadCars();
    }

    private void LoadCars()
    {
       this.Cars = new List<Car>();
       this.Cars.Add( new Ferrari() );
       this.Cars.Add( new AstonMartin() );
    }

    public int GetMaxSpeedOfAllCars()
    {
        int maxSpeed = 0;

        foreach( Car car in this.Cars )
        {
            if( car.MaxSpeed > maxSpeed )
            {
                maxSpeed = car.MaxSpeed;
            }
        }

        return maxSpeed;
    }

}
公共级车库
{
私家车列表{get;set;}
公共车库()
{
这是装载车();
}
私家货车()
{
this.Cars=新列表();
这个.Cars.Add(新法拉利());
this.Cars.Add(new AstonMartin());
}
公共int GetMaxSpeedOfAllCars()的最大速度
{
int-maxSpeed=0;
foreach(本车中的车。车)
{
如果(car.MaxSpeed>MaxSpeed)
{
maxSpeed=car.maxSpeed;
}
}
返回最大速度;
}
}

您将无法执行此操作,因为C#仅支持开关情况下的编译时常量。相反,您应该使用if/else块。

这取决于您想用它做什么。如果“开关”是给汽车额外的行为,把它放在类本身。例如,在您的情况下,您已经获得了适当的字段(ick,public fields,but…),您可以使用:

public static int GetMaxSpeed(Car car)
{
    return car.MaxSpeed;
}
在其他情况下,可以为类型指定一个方法,并且可以使用嵌套类根据不同的值以不同的方式实现这些方法。为“基类”提供一个私有构造函数和抽象方法,然后将派生类创建为嵌套类,这样它们仍然可以使用私有构造函数并公开特定值。我称这些类型为“智能枚举”

如果要将每个值映射到另一个值,请使用
字典
(或其他任何工具)。如果要将每个值映射到一个动作,请使用
字典

基本上,除非您有一个枚举或一些整数类型,否则您将无法使用switch。。。这通常是一种痛苦。使用字典通常是一种更简单的方法


如果你能给出一个不那么容易解决的更现实的例子,我们可以帮助更多…

我会根据一般原则,为这些实例创建一个字典(或只是维护一个列表),而不是打开它们。Switch语句有时是必需的,但它们很少是“可靠”代码;每当创建一种新型汽车时,您都必须更改switch语句来处理这种新情况

static void Main(string[] args)
{
    Console.WriteLine(GetMaxSpeed(Car.Ferarri));
    Console.ReadLine();
}

public static int GetMaxSpeed(string ModelType)
{
    foreach(var car in Car.Cars)
       if(car.Name == ModelType)
          return car.MaxSpeed;
}

public enum Car
{
    public int MinSpeed;
    public int MaxSpeed;
    public string Name;

    public Car(string Name, int MinSpeed, int MaxSpeed)
    {
        this.Name = Name;
        this.MinSpeed = MinSpeed;
        this.MaxSpeed = MaxSpeed;
    }

    public static List<Car> Cars = new List<Car>
    {
       new Car(Car.Ferrari, 30, 240);
       new Car(Car.VW, 10, 50);
       new Car(Car.AstonMartin, 75, 180);        
    }

    public static const string Ferrari = "Ferrari";
    public static const string VW = "VW";
    public static const string AstonMartin= "AstonMartin";
}
从C#7.0开始,您可以使用模式匹配:

       public static void RepairCar(Car BrokenCar)
    {
        switch (BrokenCar)
        {
            case { } car when car == Car.Ferrari:
                Console.WriteLine("${0} of Insurance Needed", CalculateInsurance(BrokenCar));
                // 
                // Repair Algorithm Here
                //
                break;

            case { } car when car == Car.BMW:
                System.Console.WriteLine("${0} of Insurance Needed", CalculateInsurance(BrokenCar));
                // 
                // Repair Algorithm Here
                //
                break;

            case { } car when car == Car.Audi:
                Console.WriteLine("${0} of Insurance Needed", CalculateInsurance(BrokenCar));
                // 
                // Repair Algorithm Here
                //
                break;

            default:
                Console.WriteLine("${0} of Insurance Needed", CalculateInsurance(BrokenCar));
                // 
                // Repair Algorithm Here
                //
                break;
        }
    }

a) 问题是什么?b) 为什么需要这个(这看起来很奇怪)?您不能
返回ModelType.MaxSpeed
?法拉利和阿斯顿马丁都不是那种类型;它们是这类汽车的实例。is接线员不能在这里工作。好的,我现在仔细看看,明白你的意思了。请看我的更新,我添加了一个使用多态性的更好的例子。第二个解决方案的唯一问题是,我试图让法拉利成为一个更大对象的静态属性-基本上就像有一个从事件传入的Garage类,该Garage类有一个名为Car FirstCar的静态属性,然后我想在FirstCar上切换到确定它是法拉利、大众还是其他什么-如果您需要容器类中的静态属性,只需在容器类内部和“Get”return Car.MaxSpeed中使Car实例保持静态即可。它仍然适用于多态性。但对于这种简单的情况,枚举方法是合适的。选择您喜欢的使您的实现在您的场景中更强大的选项。但是我如何能够切换Car的实例?这实际上是完美的,除非当我尝试这样做时,它告诉我它不起作用,因为切换表达式必须基于常量值-您可以尝试将Car指定为常量。如果Car是一个结构,这将特别有效。这是Java比C做得更好的一件事-在Java中,你可以使用
enum
s和属性、方法等。在C中,你可以使用公共只读实例来模拟(使用更糟糕的语法),但是你失去了使用
switch
…@BlueRaja DannyPflughoeft:是的,我非常同意(正如我在不同地方说过的:)这一点在C#7中有所改变:
       public static void RepairCar(Car BrokenCar)
    {
        switch (BrokenCar)
        {
            case { } car when car == Car.Ferrari:
                Console.WriteLine("${0} of Insurance Needed", CalculateInsurance(BrokenCar));
                // 
                // Repair Algorithm Here
                //
                break;

            case { } car when car == Car.BMW:
                System.Console.WriteLine("${0} of Insurance Needed", CalculateInsurance(BrokenCar));
                // 
                // Repair Algorithm Here
                //
                break;

            case { } car when car == Car.Audi:
                Console.WriteLine("${0} of Insurance Needed", CalculateInsurance(BrokenCar));
                // 
                // Repair Algorithm Here
                //
                break;

            default:
                Console.WriteLine("${0} of Insurance Needed", CalculateInsurance(BrokenCar));
                // 
                // Repair Algorithm Here
                //
                break;
        }
    }