• Как сбросить Балласт создаваемый библиотекой Newtonsoft.Json c#?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    Дж.Рихтер (тот самый, который CLR via С#) предлагает в таких случаях разместить библиотеку в ресурсы сборки и подгружать ее оттуда когда попросят.
    У меня это сделано так:

    В файле Program.cs
    const string DOCUMENT_FORMAT_OPEN_XML = "DocumentFormat.OpenXml, Version=2.5.5631.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
    private static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
    
                AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
                {
                    switch (e.Name)
                    {
                        case DOCUMENT_FORMAT_OPEN_XML: return Assembly.Load(Properties.Resources.DocumentFormat_OpenXml);
                        default: return null;
                    }
                };
    
                Application.Run(new MainFrom());
            }


    P.S. Создатель ILMerge прокоментировал этот способ: "Если б я знал что так можно, то бы не стал ILMerge делать".
    Ответ написан
    3 комментария
  • Как можно загрузить данные в DataGridView по мере скроллинга?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    Виртуальный режим DataGridView вам в помощь.
    А вообще вот зачем пользователю в интерфейсе 50к строк. Все равно ему столько не нужно. А накладных расходов куча: память, обращения к диску, обмен по сети (если данные берутся из удаленной базы).
    Показывайте пользователю только то, что ему нужно в данный момент или используйте пагинацию.
    Ответ написан
  • Чтение данных из com порта вешает программу. Как заставить обработчик работать в другом потоке?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    может что-то типа:

    using System.Text;
    using System.Threading.Tasks;
    using System.IO.Ports;
    using System.Windows.Forms;
    
    namespace serialport_process
    {
        class Program
        {
            class OutputForm : Form
            {
                public RichTextBox richTextBox {get ;private set;}
    
                public OutputForm()
                {
                    WindowState = FormWindowState.Maximized;
    
                    richTextBox = new RichTextBox 
                    {
                        Dock = DockStyle.Fill
                    };
                }
            }
    
            static Encoding ENCODING = Encoding.ASCII;
            const int BUFFER_SIZE = 4096;
            static byte[] buffer = new byte[BUFFER_SIZE];
    
            delegate void AppendText(string inText);
    
            static void Main(string[] args)
            {
                var form = new OutputForm();
    
                var task = new Task(() => 
                {
                    var serialPort = new SerialPort("COM1", 115200, Parity.None, 8, StopBits.Two);
    
                    serialPort.DataReceived += (sender, e) =>
                    {
                        var count = serialPort.BytesToRead;
                        while (count > 0)
                        {
                            var current_count = serialPort.Read(buffer, 0, count < BUFFER_SIZE ? count : BUFFER_SIZE);
                            var text = ENCODING.GetString(buffer, 0, current_count);
                            count -= current_count;
    
                            form.Invoke((AppendText)(txt => form.richTextBox.AppendText(txt)), text);
                        }
                    };
                    serialPort.Open();
                    while (true) ;
                });
    
                form.Load += (sender, e) => task.Start();
    
                Application.Run(form);
            }
        }
    }


    не проверял, но начал бы с этого...
    Ответ написан
  • Как найти разницу в двух экземплярах класса?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    все зависит от задачи:
    как именно сравнивать: рекурсивно, нерекурсивно
    что выдавать в результате: имена свойств, PropertyInfo, PropertyDescriptor

    если особых требований к быстродействию нет, то можно написать через рефлексию универсальный сравниватель, в том числе и рекурсивный.

    В простейшем случае, нерекурсивный вариант, который сравнивает свойства с простыми типами по значению, а ссылочные по ссылке, и выдает имена различающихся свойств:

    static IEnumerable<string> Compare<T>(T a, T b)
                where T : class
            {
                return typeof(T)
                        .GetProperties()
                        .Where(pi => !pi.GetValue(a, null).Equals(pi.GetValue(b, null)))
                        .Select(pi=>pi.Name);
            }
    Ответ написан
  • Как вывести поле в combobox?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    первый вариант:
    если можно переопределить метод ToString() у Station, то переопределите, чтоб этот метод возвращал Title.

    второй вариант:
    у comboBox1 задать свойство DrawMode отличным от Normal и с помощью обработчика события DrawItem вывести все что вам угодно.
    Ответ написан
    Комментировать
  • Как жить дальше?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    По моему мнению, ситуация вполне себе типичная. Это жизнь. Никто не будет водить вас за ручку по премудростям тех или иных технологий. Школы/институты закончились.

    Конечно, есть чисто софтверные компании, в которых много программистов, между которыми задачи параллелятся, налажен конвейер опыта: приходит джуниор, его прикрепляют к опытному старшему товарищу, а сверху за ними всеми приглядывает евангелист-архитектор со одухотворенным взглядом, который знает: как надо делать и как делать не надо.

    Но ведь у компании нет такой цели - обучить 15 программистов в год. Компания должна зарабатывать деньги.

    Если контора не чисто софтверная или просто небольшая, то смысл держать двух и более специалистов на одном направлении? Человека нанимают, чтобы он обустроил и поддерживал одну из сторон проекта. При этом он может почти не пересекаться по стеку технологий с другими участниками проекта. Обычно требуются работники работу работать. Программы сами по себе никому не нужны. Нужно решение каких-то проблем за адекватные деньги. Это может быть программа, сторонний сервис, нанятый специалист или что-то еще....

    Мне кажется, что первое, что нужно решить для себя в данной ситуации - это есть ли перспективы у вас в этой компании? Представьте: вот вы стали крутым спецом, теперь вы глубже понимаете то, что вы делаете и до кучи освоили соседние области знаний. Есть для вас место в этой компании за достойное вознаграждении? А то бывают разные случаи. Например бывает, что в фирме есть костяк из 6..10 специалистов не менявшийся последние 15 лет и текучка студентов. Или бывает что фирма насквозь пронизана блатом: вы поработаете 5 лет, а вам поставят начальником сына кого-то там сверху, только что закончившего институт. Или просто нет в фирме больших зарплат и доходов и не будет.

    А если вам не нравится инструментарий - выбирайте сами. Понятное дело, что есть бесплатные инструменты, есть платные, а есть сильно платные. Нужно найти свой инструмент. А еще есть кривые инструменты, но некоторые можно выпрямить....ну или загнуть под себя....
    Автоматизируйте рутину: тестирование, деплой, работу с версиями. Возможно ваши конфигурирования тоже можно автоматизировать.
    А "гуглить, изучать, набивать шишки" - это очень хорошо! А еще читать умные книжки. А еще изучать чужой код: хороший и плохой.

    По поводу зарплаты. Есть мнение, что чем чаще меняешь работу, тем быстрее растет зарплата. Достаточно спорное, по моему мнению, утверждение. Но, возможно, оно иногда и в зависимости от человека работает. Опять же мы говорим, что профессиональный рост, про интерес к работе, про комфорт в работе и если денег хватает...пока, то наверное стоит остаться...пока. Но часто жизнь диктует свои требования: в какой-то момент вопрос зарплаты станет приоритетнее и это будет уже совсем другая история.
    Ответ написан
    Комментировать
  • Как масштабировать svg при прокрутке колесика мвши?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    Не являюсь сильным специалистом в svg, но основной подход такой:
    смещаем все так, чтобы мышка оказалась в начале координат,
    затем масштабируем,
    затем перемещаем обратно.

    Для этого нужно рассчитать матрицу преобразования, которая будет представлять из себя матричное произведение трех матриц: матрица переноса на (-Xмыши,-Yмыши), матрица масштабирования на scale, матрица переноса на (Xмыши, Yмыши).

    Подобное реализовывал на c#:

    protected override void OnMouseWheel(MouseEventArgs e)
            {
                if (isAllowTransfom)
                {
                    var transform_local = transform.Clone();
    
                    var matrixOrder = MatrixOrder.Append;
                    var K = e.Delta > 0 ? SCALE_MUL : 1 / SCALE_MUL;
    
                    transform_local.Multiply(new Matrix(1, 0, 0, 1, -e.Location.X, -e.Location.Y), matrixOrder);
                    transform_local.Multiply(new Matrix(K, 0, 0, K, 0, 0), matrixOrder);
                    transform_local.Multiply(new Matrix(1, 0, 0, 1, e.Location.X, e.Location.Y), matrixOrder);
                    transform = transform_local;
    
                    OnViewWindowChanged(transform);
                }
    
                base.OnMouseWheel(GetWorldMouseEventArgs(e));
            }


    То есть у меня есть матрица transform, в которой содержится с каким смещением и каким масштабом отрисована картинка. При вращении колесика мыши мы эту матрицу модифицируем и все перерисовываем.
    P.S. Очень важен порядок перемножения матриц.
    Ответ написан
    Комментировать
  • Как называется такая конструкция в C#?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    Tom Nolane и flafy4 Геттеры и сеттеры нужны не только чтобы "выводить приватную переменную наружу".

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

    Есть куча более интересных применений геттеров и сеттеров, например:

    уведомить об изменении состояния объекта:
    string _StateValue;
    public string stateValue
    {
        get {return _StateValue; }
        set 
        {
            _StateValue = value;
            OnStateValueChanged(value); //этот метод генерирует событие на которое подписаны все кому интересно изменения этого поля, например при изменении поля могут по событию перерисовываться форма
        }
    }


    выполнить отложенную инициализацию поля, хотя есть и другие способы это сделать, например через Lazy:
    string _CaсhedValue = null;
    string cachedValue
    {
        get
        {
            if (_CachedValue == null)
            {
                _CachedValue = CreateValue(); //этот метод вычисляет значение
            }
            return _CachedValue; 
        }
    }


    вычисляемые свойства
    PointF _Start;
    PointF _Stop;
    PointF center 
    {
        get
        {
            return new PointF((_Start.X+_Stop.X)/2,(_Start.Y+_Stop.Y)/2);
        }
    }


    это только первое что в голову пришло...
    Ответ написан
    3 комментария
  • Использовать var или объявлять тип явно?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    Пишу везде "var", где позволяет компилятор и алгоритм (в том смысле, что иногда при создании объекта некоторого класса через "new" или при возврате объекта из метода, его нужно положить в переменную типа родительского класса или интерфейса).
    Меня в этом вопросе лень ведет: мне лень писать два раза наименование типа или вообще разбираться что там за тип и как именно он пишется.
    При создании переменных типа double я также использую "var" и суффиксы:
    var d = 5D;
    опять же из соображений лени
    Кроме того из соображений общего стиля тоже красиво писать везде "var".
    Ответ написан
    Комментировать
  • Хранение данных в C#, как лучше?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    Есть такой класс Lookup. Позволяет сопоставить одному ключу несколько значений.
    Получить объект такого типа можно из любого IEnumerable<TElement> с помощью нескольких перегруженных методов ToLookup(...).
    Ответ написан
    Комментировать
  • Какими знаниями необходимо обладать, чтобы успешно освоить радиотехнику и связанные с ней предметы в ВУЗе?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    Чтоб освоить радиотехнику в ВУЗе достаточно обладать знаниями на уровне школьной программы. Остальное должен дать ВУЗ. Весь необходимый специальный теоретический бэкграунд будет дан на первом курсе.
    Особо в начале нужно обратить внимание на теорию цепей, тервер и матстатистику. Если, например, преподаватель слаб - нужно рыть и разбираться самому. Бывают, конечно, и школы слабые, так что радиотехническое направление становится неподъемным...

    Закончил РтФ УПИ в 2005 году. Работал 7,5 лет схемотехником. 3,5 года вел практики и лабораторные по ОТЦ и РЦС.

    Вообще, нужны не знания как таковые, а действительно заниматься в ВУЗе и дома (как это предполагает учебная программа. Как потом выяснил, на самостоятельную работу по учебному плану выделено как минимум столько же часов, сколько и на работу с преподавателем.)
    Самое сложное в ВУЗе - это в 18 лет заниматься учебой, а не алкоголизмом и девочками. Серьезно.
    Ответ написан
    8 комментариев
  • Как понять комплексные числа?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    Комплексные числа отличаются от обычного 2d-вектора. 2d-вектор - это просто упорядоченная пара действительных чисел. А комплексное число хоть и является 2d-вектором (в этом понимании), но для него заданы еще некоторые правила. Например, что вы можете сказать об умножении 2d-на себя (ну, то есть возведение в квадрат)? Практически ничего. Потому что, в общем, для него не определена эта операция (хотя никто не мешает доопределить, но это будет уже не совсем 2d-вектор). А вот для комплексного числа возведение в квадрат очень даже понятно что это.

    Если следовать вашей логике представления комплексного числа как структуры, то тут больше все же подойдет класс с переопределенными операциями: сложение и вычитание (это и для 2d-вектора аналогично), умножение, деление, степень, корень, логарифм......плюс надо не забыть про экспоненциальную форму (хотя с точки зрения 2d-вектора - это всего лишь длина и ориентация).

    P.S. Я читал про разных математиков, про то как они работают с математическими абстракциями. Есть те, которые фантазируют, представляют себе все это, а есть которые используют операционалисткий подход: "я не знаю что это, но я знаю как с этим работать". Первые открывают новые математические горизонты, а вторые ставят новые теории на прочные научные рельсы и пишут толстенные монографии. Понятное дело, что это крайности и обычно каждый математик как-то визуализирует себе то, с чем он занимается....
    Ответ написан
    Комментировать
  • Как лучше убрать повтороение кода?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    Не являюсь специалистом по Java, я в основном по С# практикуюсь.
    На C# делаю через метод расширения принимающем лямбду. Если объект не null, то запускается лямбда, принимая объект как параметр. Метот расширения возвращает результат лямбды, если объект не null, и null, если объект null.
    Удобно. Можно делать цепочки вызовов не проверяя вручную на null или делать вложенные вызовы (кому как удобнее)....
    Насколько знаю в Java8 есть и методы расширения и лямбды Новое в Java8.
    Евгений Корначев видимо именно это и предлагает.
    Ответ написан
    Комментировать
  • Возможно ли создать наследуемый класс из статического метода класса-предка?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    А что если так:
    using System;
    
    namespace answer
    {
    	using System;
    	
    	public abstract class MyBaseClass<T, T2>
    		where T : class, new()
    		where T2: class, new()
    	{
    		protected T RealObject = new T();
    		public void setRealObject(dynamic realObject) {   this.RealObject = realObject;   }
    
    		public static U CreateFromBaseObject<U>(T baseObject)  where U : MyBaseClass<T>, new()
    		{
    			var t = new U();  t.setRealObject(baseObject);  return t;
    		}    
    
    		public static T2 CreateFromBaseObject(T baseObject)
    		{
    			return CreateFromBaseObject<T2>(baseObject);
    		}
    	}
    
    	public class RealDerivedClass {}
    	public class MyDerivedClass : MyBaseClass<RealDerivedClass, MyDerivedClass>{}
    	
    	public class Test
    	{
    		public static void Main()
    		{
    			RealDerivedClass realDerivedClass = new RealDerivedClass();
    			//Приходится так:
    			MyDerivedClass myRealDerivedClass = MyDerivedClass.CreateFromBaseObject<MyDerivedClass>(realDerivedClass);
    			//А хочется так:
    			MyDerivedClass myRealDerivedClass2 = MyDerivedClass.CreateFromBaseObject(realDerivedClass);
    		}
    	}
    }
    Ответ написан
    Комментировать
  • Распознавание кода, конечный автомат, лексический анализатор и прочие умные слова?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    Я так понимаю вам сюда: Синтаксический анализ и, например, сюда: yacc
    Ответ написан
    Комментировать
  • Как правильно писать тесты?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    Я помню, у меня тоже возник такой вопрос. Везде говорят: пишите тесты, код должен быть тестируемым....и тпх. Попробовал писать тесты и особо не проникся. Но все равно читал разные источники, набиралась критическая масса знаний по тестированию.
    Ключевым моментом стала книжка Марк Симан. Внедрение зависимостей в .NET. В первой части подробно описывается, что такое зависимости, как и зачем их внедрять. И после этого стало все кристально ясно.
    Код должен быть готов к тестам. Код должен быть модульным. Зависимости должны внедряться через интерфейсы, тогда в тестах тестируемому коду можно будет подсунуть любую ромашку, если она соответствует интерфейсу. И вот уже потом можно осваивать/придумывать стратегии тестирования, наименования тестов, логи, автоматический запуск, анализ покрытия и тд.
    Ответ написан
    Комментировать
  • Какую фантастику порекомендуете, где главный герой программист/инженер?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov
    Так "Марсианин" же =)
    И Таинственный остров Жюля Верна

    похожий вопрос

    Обновлено: И кстати: Айзек Азимов. Цикл про Лаки Старра. Хоть и больше приключенческое чтиво, но задачи разрешаются вполне себе инженерным способом.
    А еще, возможно, стоит обратить внимание на сериал "МакГайвер", хоть это и не книга, и не фантастика, но вполне себе в теме вопроса =)
    Ответ написан
    5 комментариев
  • Как реализовать масштабирование относительно произвольной точки?

    DmitryITWorksMakarov
    @DmitryITWorksMakarov Автор вопроса
    Сам нашел решение.

    Расписал аккуратно матрицы, вручную перемножил, получил готовую матрицу масштабирования относительно курсора, подставил в программу и все работает.

    Стал смотреть в чем дело у меня в программе.
    Оказалось: я неправильно понимал порядок перемножения матриц при применении метода Multiply(Matrix). К счастью у Multiply есть перегруженная версия с произвольным выбором порядка операндов.

    Должно быть так:

    public class DrawingAreaControl : UserControl
        {
            public DrawingAreaControl()
            {
                DoubleBuffered = true;
                transform = new Matrix();
            }
    
            public Matrix transform { get; set; }
        
            protected override void OnPaint(PaintEventArgs e)
            {
                e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    
                e.Graphics.Transform = transform;
    
                base.OnPaint(e);
            }
    
            const float SCALE_MUL = 1.05f;
            protected override void OnMouseWheel(MouseEventArgs e)
            {
                base.OnMouseWheel(e);
    
                var matrixOrder = MatrixOrder.Append;
                var K = e.Delta > 0 ? SCALE_MUL : 1 / SCALE_MUL;
                transform.Multiply(new Matrix(1, 0, 0, 1, -e.Location.X, -e.Location.Y), matrixOrder);
                transform.Multiply(new Matrix(K, 0, 0, K, 0, 0), matrixOrder);
                transform.Multiply(new Matrix(1, 0, 0, 1, e.Location.X, e.Location.Y), matrixOrder);
    
                Invalidate();
            }
        }


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