Ответы пользователя по тегу C#
  • Зачем нужны Dependency containers?

    FirstX
    @FirstX
    .net developer
    Для того, чтобы отделить мух от котлет.

    Представь, что у тебя условно есть 3 отдела. И все они между собой очень тесно связаны. Ну не могут работать друг без друга и все тут. В итоге захотел поменять что-то во втором отделе, будь добр поменяй и в остальных двух, ибо они от него напрямую зависят.

    Первое, что приходит в голову - создание абстрактных интерфейсов, через которые все взаимодействие и происходит. Ок, создали. Но абстрактные интерфейсы делать ничего не могут, на то они абстрактные. Значит где-то нужно явно создавать реализацию для этой абстракции. Становится вопрос где это делать. Создавать внутри одного класса - экземпляры другого, это уже тоже сильная связанность между ними. Для этого и придумали ящик, где будут храниться все соответствия между интерфейсами и реализациями. Захотел получить реализацию такого-то интерфейса, попросил ответственного менеджера, он сам заглянул в свой ящик и вытащил то, что тебе требуется. И назвали это все Контейнер Зависимостей (Dependency Container). То есть это конкретный инструмент для создания слабых связей между модулями.

    Ну а слабая связанность модулей и абстракции между ними дают всякие полезные фишки по типу быстрого переключения между реализациями (например реальное/тестовое окружение), позволяет проще рефакторить отдельные модули и так далее.
    Ответ написан
    Комментировать
  • Какая разница между OWINContext.Get() и его обобщенным методом?

    FirstX
    @FirstX
    .net developer
    1. habrahabr.ru/post/227351 - пункт 3, создается кастомный менеджер и явно тип не указывается. Предполагаю, что и в твоем примере - если убрать скобки с типом менеджера, ничего криминального не случится.

    2. Видимо потому, что во втором случае стоит более строгое ограничение по сигнатуре метода, чем у просто Get. А там возможно требуется использование и вызовы методов, которые определены в родительском для всех менеджеров классе UserManager. И соответственно в сигнатуре метода GetUserManager<T> стоит ограничение where <T> : UserManager.

    Скажу честно, в исходниках я не смотрел как на самом деле, но уверен на 90%, что +/- это так
    Ответ написан
    Комментировать
  • Почему метод GetEnumerator() интерфейса IEnumerable реализовывается дважды?

    FirstX
    @FirstX
    .net developer
    Для ответа на этот вопрос надо окунуться в историю. А именно был момент, когда не было Generic-типизации и был только нетипизированный интерфейс перечисления IEnumerable. А потом с приходом новой версии .Net появились обобщения (это когда явно указывается тип <T>, в твоем случае тип данных <Product>).

    Сигнатура этого интерфейса выглядит следующим образом:
    public interface IEnumerable<out T> : IEnumerable

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

    Для понимания: в старом варианте, когда ты обходил в цикле каждый элемент через foreach - тип элемента был object (все другие типы от него унаследованы). И на каждой итерации, чтобы получить свой тип Product и работать с ним - приходилось делать приведение типов.
    В новом варианте, благодаря тому, что явно указан тип <Product> при обходе в цикле - ты сразу получаешь объект типа Product.

    Рекомендую по этой теме почитать вообще изменения в .Net при переходах с версии на версию + почитать про Generic в дотнете.
    Ответ написан
    Комментировать
  • C# - как организовать множественное наследование?

    FirstX
    @FirstX
    .net developer
    Задача конечно жесть, действительно очень сложно понять конечную цель ваших манипуляций (а мотивацию для чего вы это делаете). Но немного теории на счет того, что тут происходит.

    Есть AutoCommon и есть ряд наследников У AutoCommon есть свойство DSV, и у AutoA мы снова видим определение свойства DSV. В этот момент, компилятор неявно считает, что это абсолютно новое свойство, никак не связанное с родительским (каждый остается при своем свойстве). То есть то, что написано у вас на самом деле выглядит так

    public class autoA : autoCommon{
    	public autoA(){
    		this.dvs = new dvsDizel();
    	}
         public new dvsDizel dvs {get;set;}
    
    }


    Теперь идем в конструктор и понимаем, что объект создается только для DSV, который объявлен в дочернем классе. В родительском он как был пустой, таким и остается, о нем мы ничего не говорили.

    Теперь когда мы делаем так:

    AutoCommon auto = new AutoA();
    WriteLine(auto.dsv.a);

    Что мы видим? Правильно, ничего. Почему? Да потому что мы пытаемся обратиться к свойству, которое принадлежит родительскому классу, а мы его и не создавали никогда (точнее экземпляр объекта для свойства), мы создавали свойство дочернего объекта.

    Перепишем пример так:

    public class autoA : autoCommon{
    	public autoA(){
    		base.dvs = new dvsDizel();
    	}
         public new dvsDizel dvs {get;set;}
    
    }


    Теперь мы создаем экземпляр объекта не для дочернего объекта, а именно для родителя.
    После этого пример выше, выведет нам то, что вы видимо хотели, то есть строку с текстом.
    НО при таком вызове:

    AutoA auto = new AutoA();
    WriteLine(auto.dsv.a);

    Вы опять получите эксепшен с null. Почему ? Да потому что вы обращаетесь к свойству уже дочернего объекта, которое в этот раз мы оставили пустым)

    Итого: вы имете 2 свойства в дочернем объекте (родительское и "свое") с одинаковым именем. Чтобы обратиться к родительскому используете base.* , чтобы обратиться к своему можно явно через this.*, либо this можно опустить.

    public class autoA : autoCommon{
    	public autoA(){
    		base.dvs = new dvsDizel();
                   this.dvs = base.dsv;
    	}
         public new dvsDizel dvs {get;set;}
    
    }


    В данном варианте они теперь ссылаются на один и тот же объект, но обращаясь по родительскому типу данных вы сможете получать общие методы dsv, а если сделаете приведение типов к конкретному классу AutoA, то сможете вызывать методы DvsDizel.
    Ответ написан
    9 комментариев
  • Как работает Timer в WPF?

    FirstX
    @FirstX
    .net developer
    Для общей справки в дополнение к первому ответу, есть грубо говоря 2 основных разновидности таймеров:

    1. System.Threading.Timer - Ставит задачу в пул потоков, поэтому подходит для тех, случаев, когда задача выполняется по таймеру в фоновом режиме. Например ваш объект изменяет параметр Х, но на форме этого не видно.

    2. System.Windows.Forms.Timer (для WinForms) / System.Windows.Threading.DispatcherTimer (WPF и Silvelight) и System.UI.XAML.DispatcherTimer для приложений Win Store еще есть - это все аналоги, которые вызывают исполнение метода в том же потоке, что и был вызван. Благодаря этому, обеспечивается доступ к элементам графического интерфейса, но при этом сюда лучше не помещать сложную вычислительную логику
    Ответ написан
    Комментировать
  • Как в C# осуществить выход из потока (с другого класса)?

    FirstX
    @FirstX
    .net developer
    Мне кажется задача изначально возможно так спроектирована, что получаются запутанные решения. Первая мысль про отмену выполнения потока была тоже сделать на базе CToken, но получается токен нужно передавать еще и в метод check (оттуда же вызываем отмену в данном варианте), что лично мне не не очень нравится.

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

    С другой стороны смотрите, получается метод check что-то проверяет. Значит должен возвращать результат проверки (true/ false). По результатам проверки должно приниматься решение о том, прекратить выполнение или продолжить. Мне кажется надо пересмотреть решение задачи, чтобы логика была более очевидной, а не вбросами исключений в разных местах кода.
    Ответ написан
    Комментировать
  • Как сделать AutoComplete форму в C#?

    FirstX
    @FirstX
    .net developer
    Если верно понял условие, то можно попробовать как-то так (первое что пришло в голову)

    string query = String.Format("Select name From myTable Where name LIKE '{0}%'", t.Text);
    DataTable dt = GetMusic(query);
    var names = new string[dt.Rows.Count];
    
    for (int index = 0; index < dt.Rows.Count; index++)
                    names[index] = dt.Rows[index][0].ToString();


    Вместо "myTable" наименование своей таблицы разумеется
    Ответ написан
  • Можно ли писать на C# под мобильные платформы, ориентированно WP и Android?

    FirstX
    @FirstX
    .net developer
    Ну то, что язык для desktop приложений - ложь и провокация.
    Под WP - это нативный язык.
    Насколько заверяют разработчики производительность Xamarin приложений (ios/ android) близка к нативным решениям, поэтому на самом деле основным недостатком является цена платформы. Для инди-разработчика это 299$ за 1 разрабатываемую платформу.

    Как уже выше сказали, если интересует разработка игр, то Unity позволяет писать на C# на любые мобильные платформы.

    Если вы перейдете скажем на Java для разработки под андроид, то WP/ iOs все равно мимо пройдут, потому что нет совсем универсального языка.
    Ответ написан
    Комментировать