Переключение с экземплярами объекта - PullRequest
2 голосов
/ 31 октября 2011

Редактировать

Вот другая версия кода, которая делает его немного более понятным о том, что я пытаюсь сделать:

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

Как написано, это не скомпилируетсяпотому что это не позволит мне переключить BrokenCar в методе RepairCar.Любые предложения?

Исходное сообщение

Я пытаюсь создать объект, который может хранить статические свойства и, что более важно, иметь возможность переключения - вот пример -

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

Это будет вызвано событием вне этого класса -

Ответы [ 4 ]

6 голосов
/ 31 октября 2011

Это зависит от того, что вы хотите с ним делать.Если «переключатель» должен придать автомобилю дополнительное поведение, поместите его в сам класс.Например, в вашем случае у вас уже есть соответствующее поле (ick, public fields, но ...). Вы можете просто использовать:

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

В других случаях вы можете указать типу методи вы можете использовать вложенные классы для реализации методов по-разному в зависимости от различных значений.Дайте «базовому» классу приватный конструктор и абстрактные методы, затем создайте производные классы как вложенные классы, чтобы они все еще могли использовать приватный конструктор и предоставлять конкретные значения.Я называю эти типы «умными перечислениями».

Если вы хотите сопоставить каждое значение другому значению, используйте Dictionary<Car,string> (или любой другой).Если вы хотите отобразить каждое значение в действии, используйте Dictionary<Car, Action>.

В основном вы не сможете использовать переключатель, если у вас нет перечисления или какого-либо целочисленного типа.и это обычно было бы болью.Использование словаря часто является более простым подходом.

Если вы можете привести более реалистичный пример, который не так легко решить, мы можем помочь больше ...

5 голосов
/ 31 октября 2011

Чтобы напрямую ответить на ваш вопрос, сделайте ModelType перечислением и отключите это значение.У типа Car есть свойство ModelType с именем «Model» в приведенном ниже примере.

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

Если вы хотите иметь класс 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;
    }

}
0 голосов
/ 31 октября 2011

Я бы просто на общих принципах создал словарь этих экземпляров (или просто поддерживал бы список) вместо их включения.Операторы switch иногда необходимы, но они редко представляют собой «твердый» код;каждый раз, когда создается новый тип Car, вам придется изменить оператор 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";
}

Если вам просто нужно было включить ссылки на объекты, попробуйте включить частнуюполе типа, однозначно идентифицирующее этот автомобиль;поле идентификатора.Затем вы можете сравнивать идентификаторы в операторе switch вместо ссылок.

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};
}
0 голосов
/ 31 октября 2011

Вы не сможете сделать это, потому что C # поддерживает только константы времени компиляции для случаев переключения.Вместо этого вы должны использовать блоки if / else.

...