Конечно не изменилось :) Вот только о том что ваша часть приложения не работает вместе с Васиной вы узнаете уже завтра а не через пару недель (в лучшем случае).
Цель CI это отловить проблемы интеграции как можно раньше, а не улучшить общее качество продукта.
Кстати если перед тем как запушить код в центральный репозиторий вы сначала забираете из этого репозитория все изменения, потом полностью билдите программу (с инсталаяторами или deb — пакетами например), програняете все тесты, разворачиваете на на каком-нибудь enviroment, а затем делаете smoke tests — то у вас тоже есть CI как практика.
Затем что это нужно твоим клиентским приложениям. Хром начал двигаться с такой скоростью так-как гуглу нужен производительный UI для своих Web-приложений например.
Или для популяризации своей ос — то что делает Apple.
Монада изменятся не может по определению. Как может изменяться моноид? (Монада это моноид на категории эндофункторов). А моноид это совокупность множества операции над элементами множества и единичным элементом для выбранной операции. Например для натуральных чисел может быть такой моноид — натуральные числа, сложение, число 0. В некоторых монадах (IO, State) комбинируемые функции устроены таким образом что каждая из них принимает и возвращает объект специального типа, который сам по себе не изменяемый но может каждый раз возвращаться новый.
На счет того что при неизменяемых объектах ссылки работают намного лучше вы абсолютно правы. Кстати это пришло умным людям в голову много лет назад, отсюда и термины referential transparency, и целый класс структур данных, называемых — функциональными.
По поводу первого пункта — извините но у вас ответ как у солдата-срочника, который копает от забора и до обеда, а что в итоге получится дорога или канава — его не очень интересует. Обычно когда дают ТЗ из одного предложения — профессионал спрашивает а зачем это делать. А дальше идут попытки конкретизировать что надо сделать. Определяются приоритетные фичи, разбиваются на задачи и дается эстимейт. В таком случае хорошо и вам и менеджеру. Вы четко понимаете что и зачем нужно сделать, а менеджер знает что и когда будет сделано.
Ваш сервер практически не содержит общего кода с клиентом да и используется только внутри библиотеки. Явно неплохо бы было разбить на 2. Плюс вместо наследованния лучше-бы было использовать агрегацию. Кажется что код от этого бы стал легче.
Может вам стоило смотреть в сторону Managed C++. Просто ваш код на шарпе не читаем вообще и смысла писать на шарпе вот так нет. Ну и конечно писать свою асинхронность вместо системной это полный ахтунг.
Вообще от статью осталось впечатление что опытный С/С++ разработчик пришел на .NET и не посмотрев что уже написано до него, а сразу кинулся все оптимизировать таким образом как он привык в С/С++.
На счет синхронизации — она ведь не нужна если у вас нет изменяемых состояний. Есть неплохая статья как с ними бороться. Мне например избавление от изменяемого состояния видеться куда более простым способом писать (а потом и читать) код.
Э а то что поток А удаляет ссылку на объект в потоке B это не нарушение инкапсуляции? И еще вопрос — деструктор в Делфи вызывается когда ссылок на объект не осталось или когда вызван специальный оператор (аналог delete в С++)
Хм неплохо :) Но я бы вынес код загрузки и работы с интерфейсом в тот же домен где реализация интерфейса живет. Так решается очень много проблем со временем жизни объектов и междоменным взаимодействием, да и разработчику плагина не надо парится с MarshalByRef.
Хм. Ткните пожалуйста в макро-систему на С которая позволяет работать с AST во время компиляции и встроена в компилятор? Я просто сколько на С не писал такого чуда не видел. А #define и в C# есть.
Числа будут разные от раза к разу. Без Sleep получите OutOfMemory при определенном Sleep в зависимости от вашей машины пример начнет полностью работать.
Пространство имен: System.Windows.Media.Imaging
Сборка: PresentationCore (в PresentationCore.dll)
public sealed class WriteableBitmap: BitmapSource
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
namespace My{
class MyClass
{
public static void Main(string[] argv)
{
for(var i =0; i<10000; i++)
{
new Task( () => {new WriteableBitmap();}).Start();
Console.WriteLine(i);
}
Да вобщем — то что вы написали это практически цитата — толи из Рихтера толи с МСДН. К сожалению такое руководство иногда приводит к сложно-отлавливаемым ошибкам. Вот и все. :)
Цель CI это отловить проблемы интеграции как можно раньше, а не улучшить общее качество продукта.
Кстати если перед тем как запушить код в центральный репозиторий вы сначала забираете из этого репозитория все изменения, потом полностью билдите программу (с инсталаяторами или deb — пакетами например), програняете все тесты, разворачиваете на на каком-нибудь enviroment, а затем делаете smoke tests — то у вас тоже есть CI как практика.
Или для популяризации своей ос — то что делает Apple.
На счет того что при неизменяемых объектах ссылки работают намного лучше вы абсолютно правы. Кстати это пришло умным людям в голову много лет назад, отсюда и термины referential transparency, и целый класс структур данных, называемых — функциональными.
Вообще от статью осталось впечатление что опытный С/С++ разработчик пришел на .NET и не посмотрев что уже написано до него, а сразу кинулся все оптимизировать таким образом как он привык в С/С++.
Content="{Binding (Ext:E.Icon), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"Зачем так делать? А если у меня кнопка в кнопке лежит что мне делать? правильный вариант в ControlTemplate выглядит вот так
Content="{TemplateBinding (Ext:E.Icon)}"ну или вот так, если хочется чтобы автоматическая конвертация работала
Content="{Binding (Ext:E.Icon), RelativeSource={RelativeSource TemplatedParent}}"1 что такое dataGridTable?
2 зачем заполнять масив нулями?
Пространство имен: System.Windows.Media.Imaging
Сборка: PresentationCore (в PresentationCore.dll)
public sealed class WriteableBitmap: BitmapSource
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
namespace My{
class MyClass
{
public static void Main(string[] argv)
{
for(var i =0; i<10000; i++)
{
new Task( () => {new WriteableBitmap();}).Start();
Console.WriteLine(i);
}
}
}
}