Java не поддерживает true closures , хотя использование анонимного класса, как вы используете здесь (new TimerTask() { ... }
), похоже на закрытие.
edit - См. комментарии ниже - следующее объяснение не является правильным, как указывает KeeperOfTheSoul.
Вот почему он не работает:
Переменные lastPrice
, а цена - это локальные переменные в методе main (). Объект, созданный с анонимным классом, может продолжаться до тех пор, пока метод main()
не вернется.
Когда метод main()
возвращается, локальные переменные (такие как lastPrice
и price
) будут очищены от стека, поэтому они больше не будут существовать после возвращения main()
.
Но объект анонимного класса ссылается на эти переменные. Все будет ужасно ошибочно, если объект анонимного класса попытается получить доступ к переменным после их очистки.
Сделав lastPrice
и price
final
, они больше не являются переменными, но константы. Затем компилятор может просто заменить использование lastPrice
и price
в анонимном классе со значениями констант (во время компиляции, конечно), и у вас не будет проблемы с доступом к несуществующим переменным больше .
Другие языки программирования, которые поддерживают замыкания, делают это, рассматривая эти переменные специально - следя за тем, чтобы они не уничтожались, когда метод заканчивается, так что закрытие по-прежнему может получить доступ к переменным.
@Ankur: вы могли бы сделать это:
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
// Variables as member variables instead of local variables in main()
private double lastPrice = 0;
private Price priceObject = new Price();
private double price = 0;
public void run() {
price = priceObject.getNextPrice(lastPrice);
System.out.println();
lastPrice = price;
}
}, delay, period);
}
Я наконец достиг прогресса, прочитав о том, как работает обновление. В основном, как уже упоминалось здесь , и это выпуск . При вызове метода Update состояние всей сущности, включая все достижимые сущности через свойства навигации, помечается как измененное. Если вы пытаетесь добавить бенефициаров к существующему сотруднику, SaveChanges () выбрасывает, так как он ожидает изменения записи с предоставленным первичным ключом (ключами), но не находит ни одной в базе данных. Метод обновления казался не лучшим кандидатом.
Я решил сделать метод Update из базы репозитория перезаписываемым в EmployeeRepository, как показано ниже
//Update method in the repository base
//Made method virtual to enable overriding
public virtual void Update(TEntity entity)
{
if (entity != null)
_dbSet.Update(entity);
}
//Update method from EmployeeRepository
public override void Update(Employee employee)
{
var employeeFromStore = _unitOfWork.Employees.Where(p => p.Id == employee.Id)
.Include(p => p.Beneficiaries)
.SingleOrDefault();
if (employeeFromStore != null)
{
context.Entry(employeeFromStore).CurrentValues.SetValues(employee);
//Replacing the whole collection
foreach (var beneficiary in employeeFromStore.Beneficiaries)
{
if (employee.Beneficiaries.Any())
context.Entry(beneficiary).State = EntityState.Deleted;
}
//Adding new collection
foreach (var beneficiaryToAdd in employee.Beneficiaries)
{
var newBeneficiary = new Beneficiary(beneficiaryToAdd.EmployeeId, beneficiaryToAdd.Name);
employeeFromStore.AddBeneficiary(newBeneficiary.Name);
}
}
}
Я считаю, что этот ответ можно улучшить или настроить в соответствии с конкретными ситуациями. Например, кроме очистки постоянной коллекции, можно выбрать обновление