Чтобы определить о событии простым способом:
Событие является ссылкой для делегата с двумя ограничениями
Выше два являются слабыми точками для делегатов и рассматриваются в событии. Полный образец кода, чтобы показать разницу в fiddler, находится здесь https://dotnetfiddle.net/5iR3fB .
Переключить комментарий между Event и Delegate и кодом клиента, который вызывает / присваивает значения делегировать, чтобы понять разницу
Вот встроенный код.
/*
This is working program in Visual Studio. It is not running in fiddler because of infinite loop in code.
This code demonstrates the difference between event and delegate
Event is an delegate reference with two restrictions for increased protection
1. Cannot be invoked directly
2. Cannot assign value to delegate reference directly
Toggle between Event vs Delegate in the code by commenting/un commenting the relevant lines
*/
public class RoomTemperatureController
{
private int _roomTemperature = 25;//Default/Starting room Temperature
private bool _isAirConditionTurnedOn = false;//Default AC is Off
private bool _isHeatTurnedOn = false;//Default Heat is Off
private bool _tempSimulator = false;
public delegate void OnRoomTemperatureChange(int roomTemperature); //OnRoomTemperatureChange is a type of Delegate (Check next line for proof)
// public OnRoomTemperatureChange WhenRoomTemperatureChange;// { get; set; }//Exposing the delegate to outside world, cannot directly expose the delegate (line above),
public event OnRoomTemperatureChange WhenRoomTemperatureChange;// { get; set; }//Exposing the delegate to outside world, cannot directly expose the delegate (line above),
public RoomTemperatureController()
{
WhenRoomTemperatureChange += InternalRoomTemperatuerHandler;
}
private void InternalRoomTemperatuerHandler(int roomTemp)
{
System.Console.WriteLine("Internal Room Temperature Handler - Mandatory to handle/ Should not be removed by external consumer of ths class: Note, if it is delegate this can be removed, if event cannot be removed");
}
//User cannot directly asign values to delegate (e.g. roomTempControllerObj.OnRoomTemperatureChange = delegateMethod (System will throw error)
public bool TurnRoomTeperatureSimulator
{
set
{
_tempSimulator = value;
if (value)
{
SimulateRoomTemperature(); //Turn on Simulator
}
}
get { return _tempSimulator; }
}
public void TurnAirCondition(bool val)
{
_isAirConditionTurnedOn = val;
_isHeatTurnedOn = !val;//Binary switch If Heat is ON - AC will turned off automatically (binary)
System.Console.WriteLine("Aircondition :" + _isAirConditionTurnedOn);
System.Console.WriteLine("Heat :" + _isHeatTurnedOn);
}
public void TurnHeat(bool val)
{
_isHeatTurnedOn = val;
_isAirConditionTurnedOn = !val;//Binary switch If Heat is ON - AC will turned off automatically (binary)
System.Console.WriteLine("Aircondition :" + _isAirConditionTurnedOn);
System.Console.WriteLine("Heat :" + _isHeatTurnedOn);
}
public async void SimulateRoomTemperature()
{
while (_tempSimulator)
{
if (_isAirConditionTurnedOn)
_roomTemperature--;//Decrease Room Temperature if AC is turned On
if (_isHeatTurnedOn)
_roomTemperature++;//Decrease Room Temperature if AC is turned On
System.Console.WriteLine("Temperature :" + _roomTemperature);
if (WhenRoomTemperatureChange != null)
WhenRoomTemperatureChange(_roomTemperature);
System.Threading.Thread.Sleep(500);//Every second Temperature changes based on AC/Heat Status
}
}
}
public class MySweetHome
{
RoomTemperatureController roomController = null;
public MySweetHome()
{
roomController = new RoomTemperatureController();
roomController.WhenRoomTemperatureChange += TurnHeatOrACBasedOnTemp;
//roomController.WhenRoomTemperatureChange = null; //Setting NULL to delegate reference is possible where as for Event it is not possible.
//roomController.WhenRoomTemperatureChange.DynamicInvoke();//Dynamic Invoke is possible for Delgate and not possible with Event
roomController.SimulateRoomTemperature();
System.Threading.Thread.Sleep(5000);
roomController.TurnAirCondition (true);
roomController.TurnRoomTeperatureSimulator = true;
}
public void TurnHeatOrACBasedOnTemp(int temp)
{
if (temp >= 30)
roomController.TurnAirCondition(true);
if (temp <= 15)
roomController.TurnHeat(true);
}
public static void Main(string []args)
{
MySweetHome home = new MySweetHome();
}
}
Это как раз тот вариант использования для git-cherry-pick
git checkout maintenance
git cherry-pick <commit from master>
Да, это считается подбором вишен и нет, в целом не должно вызывать проблем. Если фиксация не применяется аккуратно при обратном переносе, вы можете столкнуться с точно таким же конфликтом при ее обратном выборе.
Как правило, я использую слияние для перемещения изменений «вверх» по дереву (от обслуживания к главному) и перебазирование, чтобы переместить их «вниз» по дереву (от главного к обслуживанию). Это сделано для того, чтобы порядок коммитов в главной ветке поддерживался.
Rebase по сути откатывает все ваши изменения в текущей ветке до вилки (или последней перезагрузки), копирует более новые изменения и затем повторно применяет ваши изменения.
Если вы не хотите получать все изменения от мастера, то вам, вероятно, придется выбирать те, которые вам нужны.
Гас небрежно упомянул DB Ghost (выше) - я использую его как потенциальное решение.
Краткий обзор того, как моя компания использует DB Ghost:
Процесс «обновления» включает в себя создание чистого 'исходная' БД, а затем (после предварительного обновления пользовательских скриптов) сравнение схем исходной и целевой БД. DB Ghost обновляет целевую базу данных в соответствии с
. Мы регулярно вносим изменения в производственные базы данных (у нас 14 клиентов в 7 различных производственных средах), но неизбежно развертываем достаточно большой набор изменений с помощью исполняемого файла обновления DB Ghost (созданного во время нашей сборки процесс). Любые производственные изменения, которые не были зарегистрированы в источнике (или которые не были возвращены в соответствующую выпускаемую ветвь), УТЕРЯНЫ. Это вынудило всех последовательно регистрировать изменения.
Подводя итог:
Этот рабочий процесс (отчасти) описан в Раннее устранение конфликтов / зависимостей между тематическими ветками. сообщение в блоге, написанное Джунио С. Хамано, сопровождающим git.
Выбор вишни приводит к дублированной фиксации ], что в дальнейшем может вызвать проблемы при слиянии или перемещении. Рабочий процесс на основе тематических веток хранит только одну копию исправления.