2013-09-18 3 views
2

Я хочу сделать что-то вроде этого:Список - как найти товар по ссылке?

class BaseClass 
{ 
    private List<MyClass> list; 

    private void addData() 
    { 
     list.Add(new MyClass(this)); 
    } 

    public void removeData(MyClass data) 
    { 
     list.Remove(data); 
    } 
} 

class MyClass 
{ 
    private BaseClass baseClass; 

    public MyClass(BaseClass baseClass) 
    { 
     this.baseClass = baseClass; 

     // DO SOMETHING 

     calculationDone(); 
    } 

    private void calculationDone() 
    { 
     baseClass.removeData(this); 
    } 
} 

Моя проблема заключается в том, что list.Remove() возвращает ложь и элемент не удаляется из списка. Что случилось с моим кодом?

ответ

3

Это проблема времени.

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

Только тогда, когда конструктор (и расчет) сделан, это элемент, добавленный в список.

public MyClass(BaseClass baseClass) 
{ 
    this.baseClass = baseClass; 

    // DO SOMETHING 

    calculationDone(); 
} 

Последовательность в вашем коде:

  • AddData()
    • конструктор X
      • calculationDone
      • list.Remove (X) // терпит неудачу, X не Найдено
    • List.Add (X)

Мораль здесь не поставить всю работу (всю жизнь) объекта в конструкторе. Когда вы разбиваете конструктор и вычисляете его:

private void addData() 
{ 
    var temp =new MyClass(this); 
    list.Add(temp); 
    temp.DoCalculations(); // includes calculationDone() 
} 

, и это будет работать должным образом.

+0

list.add внутри * private * метод BaseClass, и неясно, где он вызван. – Tigran

+0

@tigran - зачем это важно? –

+0

", прежде чем экземпляр мог быть назначен списку в вызывающем методе." Как насчет таинственного блока «// DO SOMETHING»? Я предполагаю, что это добавлено оттуда, в этом нет никакого смысла. – dasblinkenlight

0

Потому что this в одном классе отличается от this в другом.

class BaseClass 
{ 
    .... 
    list.Add(new MyClass(this)); //new MyClass created and pushed on the list 
    ... 
} 

и внутри MyClass

class MyClass { 
    private void calculationDone() 
    { 
    baseClass.removeData(this); //this is not inside the list 
    } 
} 

Другими словами: вы должны создать ассоциацию между вашими MyClass объектами и BaseClass, так что вы можете достичь правильных экземпляру из MyClass.

+0

Но оба варианта соответствуют правильным параметрам и должны иметь правильные значения. –

+0

@HenkHolterman: это, называемое внутри MyClass, возможно, не может быть таким, что присутствует внутри списка, и это не в случае OP (по крайней мере, в соответствии с поведением, описанным в вопросе). – Tigran

+0

'this' является тем же самым в контексте наследование. – James

0

Последовательность событий, когда addData называется является:

  1. new MyClass(this) называется, который
  2. Запускает MyClass(baseClass) конструктор, который
  3. вызывает метод calculationDone, который
  4. пытается удалить объект из base
  5. Сбой при сбое, потому что объект не добавлен
  6. Конструктор заканчивается
  7. Товар добавлен в список.

Итак, вы удаляете экземпляр MyClass из списка, прежде чем он будет добавлен. Я бы предложил избегать любого тяжелого подъема в конструкторе и отключить его до метода Execute (или аналогично названного).

Смежные вопросы