Ответы пользователя по тегу .NET
  • Почему вес файла меньше ожидаемого?

    @Sing303
    В первом случае вы узнаёте размер файла
    Во втором случае вы узнаёте длину строки filePath в байтах
    Ответ написан
    5 комментариев
  • Я сделал Code Review, может быть я где-то ошибся или у вас есть что добавить?

    @Sing303
    Опишу, как бы комментировал я
    public sealed class DataProvider : IDisposable
    {
        // nit: Предложил бы названия firstValue, secondValue либо более осмысленные, если возможно
        public extern int LongRunningCalculation(int value, int value2);
        public extern void Dispose();
    }
    
    // nit: сразу бы хотелось видеть уровень доступа и sealed (если класс не планируется наследовать)
    // Class2 - дать нормальное имя
    // { - перенести на 2ю строку по рекомендациям code style от microsoft (если не принято иных)
    class Class2 {
        // Синхронизация не нужна, если убрать метод Init, а Create вызвать в статическом конструкторе
        private readonly object _sync = new object();
        
        // _ht - дать осмысленное название
        // Судя по использованию, value может быть int`ом. Не зачем иметь лишний boxing и проверки на тип
        // _ht статический, значит к нему могут быть обращения из разных потоков, лучше сделать его ConcurrentDictionary
        // Прям сходу не могу сказать, но, возможно, использовал бы какой то другой тип Dictionary <key, key, val> (самописный или существующий), кажется, так было бы быстрее чем массив в ключе
        private static Dictionary<int[], object> _ht; 
    
        // nit: хотелось бы имена со смыслом
        public int GetValue(int index, int index2)
        {
            // Лишний метод, удалить. Create вызовем в static конструкторе
            Init();
            // Если ключ у нас объект, то необходимо реализовать IEqualityComparer для этого Dictionary (иначе не понятно как по нему искать)
            var key = new[] {index, index2};
            // Проверка на тип не нужна, Dictionary сделаем типа int
            if (_ht.ContainsKey(key) & _ht[key].GetType() == typeof(int))
                // приведение типов больше не нужно
                return ((int)_ht[key]);
            // nit: else не обязателен
            else
                // int не может быть null, будет ошибка, вернуть либо default, либо возвращаемое значение должно быть int?
                return null;
        }
    
        // Метод удалить, вызовем Create в статическом конструкторе без lock
        public void Init() 
        {
            if (_ht == null)
                lock (_sync)
                    Create();
        }
        
        // Нет смысла делать метод public, сделать private
        public static void Create() 
        {
            // nit: и так видно какой тип создаём, можно использовать var
            // Обернуть в using
            DataProvider provider = new DataProvider();
            
            // Тут следует инициализировать значение _ht, т.к. ранее оно нигде не создаётся
            // Не забыть передать реализацию IEqualityComparer в конструктор
            
            // nit: хотелось бы видеть использование фигурных скобок (если не принят иной code style)
            // nit: вместо int можно var
            // i и j, похоже, несут какой то смысл, можно попробовать придумать нормальное название (иначе не понятно почему 100 и 12, их можно в константы класса)
            // nit: возможно можно использовать Parallel.ForEach
            for (int i = 0; i < 100; i++)
                for (int j = 1; j <= 12; j++)
                    _ht[new [] { i, j }] = provider.LongRunningCalculation(i, j);
        }
    }

    А переписал бы так (если не убирать массив в dictionary)
    public interface IDataProvider : IDisposable
    {
        int LongRunningCalculation(int firstValue, int secondValue);
    }
    
    public sealed class DataProvider : IDataProvider
    {
        public extern int LongRunningCalculation(int firstValue, int secondValue);
        public extern void Dispose();
    }
    
    public sealed class DataProviderService
    {
        public DataProviderService(IDataProvider dataProvider)
        {
            _dataProvider = dataProvider;
        }
    
        private static readonly ConcurrentDictionary<int[], int?> _calculatedCache = new ConcurrentDictionary<int[], int?>(new CalculatedEqualityComparer());
        private readonly IDataProvider _dataProvider;
    
        public int? GetValue(int firstValue, int secondValue)
        {
            var isNotSupportedValues = firstValue > 100 || firstValue < 0 || secondValue < 1 || secondValue > 12;
            if (isNotSupportedValues)
            {
                return null;
            }
    
            var key = new[] { firstValue, secondValue };
            if (!_calculatedCache.TryGetValue(key, out var result))
            {
                result = _dataProvider.LongRunningCalculation(firstValue, secondValue);
                _calculatedCache.TryAdd(key, result);
            }
            
            return result;
        }
    }
    Ответ написан
    5 комментариев
  • Cast vs Convert vs Parse?

    @Sing303
    Cast - если возможно, лучше использовать его (не всегда есть возможность)
    Parse - создан для работы со строками, если у вас есть строка, в которой хранится число, то лучше использовать этот вариант. Важно помнить, что если строка будет равна null, то метод выкинет исключение ArgumentNullException
    Convert - для строк вызывает внутри себя метод Parse, при этом, если строка null, то метод не выкидывает исключение, а возвращает 0. Так же он может принимать любой объект, который реализует интерфейс IConvertible, поэтому его лучше использовать когда не известно, что именно строка придёт в метод. Ещё у Convert есть возможность конвертировать в любой тип в generic методах. Для строк Parse чуть чуть отработает быстрее, чем Convert

    P.S. В интернете куча ответов на этот вопрос, учитесь искать на английском - 95% информации там
    Ответ написан
    Комментировать
  • Как обмануть оптимизатор C#?

    @Sing303
    Вопрос в том, зачем вы так делаете, когда есть ResetEvent`ы
    Ответ написан
    Комментировать
  • Как реализовать алгоритм word wrap?

    @Sing303
    Используйте StringBuilder вместо ReadyRezult += Word + " "
    Ответ написан
    Комментировать
  • Как правильно приостановить и продолжить выполнение Task из другого потока?

    @Sing303
    Это делается с помощью системных событий
    Ответ написан
    Комментировать
  • Какова правильная логика обновления клиента игры?

    @Sing303
    Патчи
    - Не эффективно
    - Слишком сложно, чревато ошибками
    - Усложнится поддержка и скорость выпуска патча, его тестирование

    Как можно сделать (упрощённая схема)
    1. Получаем с сервера список файлов и их хешей (всех)
    2. Проверяем есть ли у пользователя все эти файлы (если хеш не корректен, считаем что файла нет)
    3. Закачиваем по 1 запакованному файлу с сервера (не архив со всеми файлами, а именно по одному)
    4. Распаковываем файлы, с заменой
    5. Наслаждаемся обновлённой версией

    Можно не считать хеш постоянно, а сохранять значение хеша локально и если дата файла изменилась, тогда считать хеш снова.
    Данная схема очень проста, нет никаких патчей, качаются только те файлы, которые нужны, не нужно даже хранить номер версии, т.к. проверка по файлам.
    Ответ написан
    1 комментарий
  • Стоит ли использовать .NET framework 4.0?

    @Sing303
    А какая у вас цель?
    Если программа полезная, то не думаю, что пользователи откажутся поставить нужную версию .NET
    Например, в Windows 8 и выше, .NET 3.5 вообще отключён в компонентах по умолчанию
    Собираетесь ли вы использовать возможности .NET 4.0?

    Для новых проектов я бы использовал всегда последнюю версию
    Ответ написан
    Комментировать
  • Как подключиться к именованному каналу без прав администратора?

    @Sing303
    Серверному нужны такие настройки
    var pipeSecurity = new PipeSecurity();
    pipeSecurity.SetAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null), PipeAccessRights.ReadWrite, AccessControlType.Allow));


    WindowsIdentity.GetCurrent().Name - это имя пользователя службы, т.к. в службе от системы выполняется
    Ответ написан
  • Как тестировать legacy код?

    @Sing303
    Это довольно таки стандартный способ тестирования legacy кода.
    Другой вариант, использовать неограниченные ферймворки.
    Ответ написан
    Комментировать
  • Как писать тесты в asp.net mvc не затрагивая Entity Framework?

    @Sing303
    Вариант 1:
    Использовать неограниченные фреймворки, на подобии Typemock, он позволит подделывать что угодно, приватные и статические методы

    Вариант 2:
    Использовать репозиторий. Необходимость использовать Typemock говорит о том, что код "плохо пахнет" и в нём явно что-то не так.
    Ответ написан
    Комментировать
  • C#. Операторы доступа для сокрытия, но не для защиты?

    @Sing303
    Инкапсуляция позволяет повысить надёжность программы и делает код более самодокументированным.

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

    Не понятно, почему вы не хотите следовать инкапсуляции в своих проектах, разве это добавляет сложности?
    Ответ написан
    1 комментарий
  • C#. Где может быть полезна явная реализация интерфейса?

    @Sing303
    Тут кратко описывается, зачем нужны интерфейсы
    sergeyteplyakov.blogspot.ru/2014/12/what-are-inter...
    Ответ написан
    Комментировать