2016-02-21 5 views
2

Я занят очень маленьким консольным приложением для C#. Я просто новичок в C#, и я знаком с Java. Моя школа дала задание создать консольное приложение, которое имитирует автодилера. Я уже написал кучу кода для добавления автомобилей с помощью консоли. Такие вещи, как бренд, тип и максимальная скорость, уже реализованы. Единственное, что мне еще нужно понять, это создание и инкрементное создание идентификатора для автомобиля. Разумеется, он будет уникальным.Auto increment ID C#

Мой первый подход делал поле id статическим и увеличивал его в конструкторе, так что каждый раз, когда объект создается, id получает ++;

Я видел выделение людей на stackoverflow, которые делали все, но решения не работали или где большие.

Это мой код;

class Car : Vehicle 
{ 
    public string brand { get; set; } 
    public string type { get; set; } 
    public int maxSpeed { get; set; } 
    public double price { get; set; } 
    public static int carID { get; set; } 



    public Car(string _brand, string _type, int _maxspeed, double _price) 
    { 
     this.brand = _brand; 
     this.type = _type; 
     this.maxSpeed = _maxspeed; 
     this.price = _price; 
     this.carID++; 

    } 
} 

Я добавил 3 авто в мой список, но в результате все автомобили имеют ID 3;

Возможно, кто-то может мне помочь, спасибо заранее.

+2

Статическая переменная разделяется между всеми экземплярами класса. Увеличение его в конструкторе делает все экземпляры, уже созданные для этого класса, использует одинаковое добавочное значение. – Steve

+0

Спасибо за быстрый и полезный ответ, но моя программа не нужна concurrenc –

ответ

1

Просто для удаления статического и добавить блокировки секции для предотвращения дубликата ИДС

class Car : Vehicle 
{ 
    private static object sync = new object(); 
    private static int _globalCount; 
    public string brand { get; set; } 
    public string type { get; set; } 
    public int maxSpeed { get; set; } 
    public double price { get; set; } 
    public int carID { get; set; } 



    public Car(string _brand, string _type, int _maxspeed, double _price) 
    { 
     this.brand = _brand; 
     this.type = _type; 
     this.maxSpeed = _maxspeed; 
     this.price = _price; 
     lock (sync) 
     { 
     this.carID = ++globalCount; 
     } 
    } 
} 
+0

Итак, у каждого автомобиля есть идентификатор 1 с этим кодом? –

+0

Спасибо за быстрый и полезный ответ, но моя программа не нуждается в параллелизме –

0

Статическая переменная разделяется между всеми экземплярами класса.
Приращение его в конструкторе делает все экземпляры этого класса «видят» последнее значение, назначенное статической переменной.

Вы должны создать переменную (не статическую) обычного экземпляра carID и использовать защищенную статическую переменную, определенную в базовом классе, для захвата текущего значения во время конструктора, присвоения переменной экземпляра carID и последующего увеличения значения базового класса.

class Vehicle 
{ 
    protected static int FakeID = 1; 
} 

class Car : Vehicle 
{ 
    public string brand { get; set; } 
    public string type { get; set; } 
    public int maxSpeed { get; set; } 
    public double price { get; set; } 
    public int carID { get; set; } 

    public Car(string _brand, string _type, int _maxspeed, double _price) 
    { 
     this.brand = _brand; 
     this.type = _type; 
     this.maxSpeed = _maxspeed; 
     this.price = _price; 
     this.carID = base.FakeID++;; 

    } 
} 

void Main() 
{ 
    Car a = new Car("xyz", "Auto", 120, 12000); 
    Car b = new Car("kwx", "Moto", 180, 8000); 

    Console.WriteLine(a.carID); 
    Console.WriteLine(b.carID); 
} 

Имейте в виду, что это будет работать правильно, если ваш код не использует многопоточный доступ к конструктору. В случае многопоточности вы должны смотреть на Interlocked.Increment

+0

Спасибо за быстрый и полезный ответ –

+0

Ну, тогда вам не нужно беспокоиться о Interlocked.Increment или других способах защиты статической переменной от одновременных изменений , Код выше должен работать так, как вы ожидаете – Steve

2
class Car : Vehicle 
{ 
    public string brand { get; set; } 
    public string type { get; set; } 
    public int maxSpeed { get; set; } 
    public double price { get; set; } 
    public int carID { get; private set; } 

    public static int globalCarID; 



    public Car(string _brand, string _type, int _maxspeed, double _price) 
    { 
     this.brand = _brand; 
     this.type = _type; 
     this.maxSpeed = _maxspeed; 
     this.price = _price; 
     this.carID = Interlocked.Increment(ref globalCarID); 
    } 
} 

Это поддерживает глобальный идентификатор счетчика и увеличивает его атомарной, чтобы сделать его поточно-безопасным.

Обратите внимание, что первый идентификатор, назначенный таким образом, будет 1. Вы можете инициализировать globalCarID с -1, чтобы начать с 0.

+0

У меня также есть коммутатор с несколькими опциями, вариант 1: печать автомобилей, вариант 2 добавления автомобилей и т. Д. Когда я печатаю автомобили, набрав 1 на консоль, он хорошо печатает с id 1 2 3 (я добавил, конечно, 3 машины). Когда я напечатаю их снова, получите идентификаторы 4, 5 и 6. Как это могло произойти. Я также пробовал решения ниже, но никто не добился успеха –