Как я переопределяю Список <T>, Добавляет метод в C#?

Я не думаю, что ваше определение таблицы подходит для того, что вы хотите достичь. В частности, line_id и line_text определены как не нулевые. Проблема заключается в том, что оператор вставки выполняет ненулевые тесты до срабатывания триггера и дает сбой (я предполагаю, что ваша вставка имеет значение только order_id и, возможно, line_text). Возможно, вы захотите посмотреть на установку значений по умолчанию. Например.

drop table if exists line_item;
CREATE TABLE `line_item` (
  `order_id` INT NOT NULL,
  `line_id` INT not null default 0,
  `line_text` VARCHAR(100) not null default '',
  PRIMARY KEY (`order_id`, `line_id`) #,
  #CONSTRAINT `FK_order_line_item`
  #  FOREIGN KEY (`order_id`)
  #  REFERENCES `myDb`.`order` (`order_id`)
  #  ON DELETE NO ACTION
  #  ON UPDATE NO ACTION)
  );

 drop trigger if exists t;
 delimiter $
 create trigger t before insert on line_item 
 for each row
 BEGIN
DECLARE i INT;
    SELECT  MAX(line_id) + 1
    INTO    i
    FROM    line_item
    WHERE   order_id = NEW.order_id;
    SET NEW.line_id = COALESCE(i, 1);
END $
delimiter $

insert into line_item (order_id) values (1),(1);
Query OK, 2 rows affected (0.05 sec)
Records: 2  Duplicates: 0  Warnings: 0

+----------+---------+-----------+
| order_id | line_id | line_text |
+----------+---------+-----------+
|        1 |       1 |           |
|        1 |       2 |           |
+----------+---------+-----------+
2 rows in set (0.00 sec)

Я не использую phpmyadmin и понятия не имею, почему он показывает предупреждение, но я предлагаю вам запустить вставку из командной строки sql, чтобы посмотреть, какую ошибку он выдает.

34
задан quakkels 4 June 2014 в 21:58
поделиться

8 ответов

Во-первых, Вы не можете переопределить, Добавляют и все еще имеют полиморфизм против Список , означая, что, если Вы используете новое ключевое слово и Ваш класс, снят как Список, Ваши новые Добавляют, что метод не назовут.

115-секундный, я предлагаю, чтобы Вы изучили Очередь класс, как, что Вы пытаетесь сделать, больше очереди, чем это - список. Класс оптимизирован для точно, что Вы хотите сделать, но не имеет никакого вида ограничителя размера.

, Если Вы действительно хотите, чтобы что-то действовало как Список, но работа как Очередь с максимальным размером, я предлагаю, Вы реализуете IList и сохраняете экземпляр Очереди для хранения элементов.

, Например:

public class LimitedQueue<T> : IList<T>
{
  public int MaxSize {get; set;}
  private Queue<T> Items = new Queue<T>();
  public void Add(T item)
  {
    Items.Enqueue(item);
    if(Items.Count == MaxSize)
    {
       Items.Dequeue();
    }
  }
  // I'll let you do the rest
}
43
ответ дан Randolpho 27 November 2019 в 15:49
поделиться

Можно также реализовать добавить метод через

public new void Add(...)

в производном классе для сокрытия, существующие добавляют и представляют функциональность.

Редактирование: Грубая Схема...

class MyHappyList<T> : List<T>
{
    public new void Add(T item)
    {
        if (Count > 9)
        {
            Remove(this[0]);
        }

        base.Add(item);
    }
}

Просто примечание, изображенное, это подразумевалось, но необходимо всегда ссылаться пользовательский список фактическим типом и никогда базовым типом / интерфейс, поскольку метод сокрытия только доступен типу и дальнейшим производным типам.

66
ответ дан Quintin Robinson 27 November 2019 в 15:49
поделиться

Вы не можете переопределить, Добавляют (), это не виртуальный метод. Произойдите из IList вместо этого и используйте частного члена Очереди для реализации.

26
ответ дан Hans Passant 27 November 2019 в 15:49
поделиться

Вы могли расшириться Система. Наборы. ObjectModel. Набор и переопределение метод InsertItem для получения поведения, которое Вы хотите, и это также, реализует IList

18
ответ дан Lee 27 November 2019 в 15:49
поделиться

Можно просто записать класс, который реализует IList<T>, который содержит внутреннее List<T>, и запишите собственные методы.

8
ответ дан Ryan Emerle 27 November 2019 в 15:49
поделиться

На лучшее кажется, что я могу сделать, это:

class MostRecentList<T> : System.Collections.Generic.List<T> {
        private int capacity;

        public MostRecentList(int capacity) : base() {
            this.capacity = capacity;
        }

        public new void Add(T item) {
            if (base.Count == capacity) {
                base.RemoveAt(0);
            }
            base.Add(item);
        }
}

Начиная с add() метод не отмечен как виртуальный.

5
ответ дан shinyhappydan 27 November 2019 в 15:49
поделиться

Имейте чтение принцип замены Лисков , Ваш набор является очень бедным кандидатом для расширения Списка <T>, это даже не великий кандидат для реализации IList<T>.

, Какие шаблоны чтения требуются на этих данных? Если только необходимо посмотреть на все текущие записи, затем реализовав IEnumerable<T>, и Добавление (T) метод должно быть достаточным для запуска с.

Это может затем быть реализовано частной Очередью (или Двухсторонняя очередь была бы лучше, но такой набор потребует некоторых других наборов API, и я не предлагаю, чтобы Вы попытались реализовать тот сами), к которому Вы Ставите в очередь () во время Добавления (с Двухсторонней очередью в случае необходимости для поддержания размера).

Примечание, что реализация IEnumerable и обеспечение Добавить метода означают Вас, может все еще использовать синтаксис инициализатора Набора при необходимости.

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

1
ответ дан ShuggyCoUk 27 November 2019 в 15:49
поделиться

Вы могли смотреть на библиотеку набора C5. У них есть ArrayList< T> это реализует IList< T> и имейте виртуальное, Добавляет метод. Библиотека набора C5 является потрясающим набором списков, очередей, стеки и т.д... Можно найти библиотеку C5 здесь:

http://www.itu.dk/research/c5/

1
ответ дан JohannesH 27 November 2019 в 15:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: