使用对象实例切换

问题描述 投票:0回答:5

编辑

这是代码的不同版本,可以让我更清楚地了解我想要做什么:

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;
        }
    }

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

c# object properties switch-statement
5个回答
9
投票

要直接回答您的问题,请将 ModelType 设为枚举并关闭该值。在下面的示例中,让 Car 类型具有名为“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;
    }
}

但更好的问题是,为什么不使用多态性?您可以将 Car 设为基本类型,并让不同的模型继承它。基本 Car 类型应具有 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 );
}

如果您想要一个带有汽车列表的 Garage 类,它看起来像下面这样。请记住,这是非常粗糙的代码,但它向您展示了我在评论中谈论的内容。

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;
    }

}

8
投票

这取决于您想用它做什么。如果“开关”是为了给汽车带来额外的行为,请将其放在类本身中。例如,在您的情况下,您已经获得了适当的字段(ick,公共字段,但是......)您可以使用:

public static int GetMaxSpeed(Car car)
{
    return car.MaxSpeed;
}

在其他情况下,您可能会给类型一个方法,并且可以使用嵌套类根据不同的值以不同的方式实现方法。为“基”类提供私有构造函数和抽象方法,然后将派生类创建为嵌套类,以便它们仍然可以使用私有构造函数并公开特定值。我将这些类型称为“智能枚举”。

如果要将每个值映射到另一个值,请使用

Dictionary<Car,string>
(或其他)。如果要将每个值映射到一个操作,请使用
Dictionary<Car, Action>

基本上你不会能够使用switch,除非你有一个枚举或某种整数类型......这通常会很痛苦。使用字典通常是一种更简单的方法。

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


7
投票

从 C# 7.0 开始,您可以使用模式匹配:

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

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

            case var 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;
        }
    }

2
投票

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


1
投票

仅根据一般原则,我会创建这些实例的字典(或仅维护一个列表),而不是打开它们。 Switch 语句有时是必要的,但它们很少是“SOLID”代码;每当创建新类型的汽车时,您都必须更改 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";
}

如果您只需要打开对象引用,请尝试打开唯一标识该汽车的私有积分类型字段; ID 字段。然后,您可以在 switch 语句中比较 ID,而不是引用。

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

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

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

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

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

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

    public static Car Ferrari = new Car(30, 240){Id = 1};
    public static Car VW = new Car(10, 50){Id = 2};
    public static Car AstonMartin = new Car(75, 180){Id = 3};
}
© www.soinside.com 2019 - 2024. All rights reserved.