Ответы пользователя по тегу C#
  • Как отсортировать слова в тексте по количеству вхождений заданного символа?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Сделайте словарь Dictionary, в нём в цикле увеличивайте на единицу на каждое слово. В результате на каждое слово будет количество каждого найденного слова. Потом преобразовать словарь в список и отсортировать его (см. пример здесь).
    Ответ написан
    Комментировать
  • "switch case" - плохо?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Конечно, если свич улучшит код, то нужно его использовать. Пример со стопкой if-ов - тот самый случай. Но свич не всегда может быть применим.
    Но иногда бывает так, что, хоть и можно сделать свичем, но лучше сделать условием, например, условие if (a>10 && a<=20) лучше, чем взять десять кейсов.

    P.S. Я как-то делал одну программу - эмулятор процессора, с выполнением пользовательского кода на ассемблере. Тот процессор имеет около сотни инструкций, и я сделал 100+ кейсов, для каждой инструкции в кейсе вызывался метод. В принципе, было достаточно удобно, я разделил кейсы на группы, и разделял их комментариями (чтобы удобнее искать по коду). Но сейчас я сделал бы по-другому - я сделал бы иерархию классов, и вызывал бы обработчик с помощью чего-то подобного: Processor.Execute(instruction), и не нужно было бы делать сотню кейсов.
    (Это было в 2004-м году, писал на Delphi.)
    Ответ написан
    Комментировать
  • C#. Где может быть полезна явная реализация интерфейса?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Я иногда делаю в классе и обычный метод, и явно реализуемый, с тем же именем, для удобства.
    Например, иногда нужен компарер как объект с методом, а иногда объект не нужен, и тогда можно вызывать статический метод.
    public class NaturalComparer : IComparer<string>
    {
    	[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
    	private static extern int StrCmpLogicalW(string psz1, string psz2);
    
    	public static int Compare(string x, string y)
    	{
    		return StrCmpLogicalW(x, y);
    	}
    
    	int IComparer<string>.Compare(string x, string y)
    	{
    		return StrCmpLogicalW(x, y);
    	}
    }
    
    public class TestApp
    {
    	public static void Main()
    	{
    		// Используем явную реализацию
    		var arr = new [] { "a5", "a1", "a10", "a3", "a7" };
    		Array.Sort(arr); // a1, a10, a3, a5, a7
    		Array.Sort(arr, new NaturalComparer()); // a1, a3, a5, a7, a10
    
    		// Используем статический метод
    		var list = new List<string> { "a5", "a1", "a10", "a3", "a7" };
    		const string max = "a4";
    		var minElements1 = list.Where(s => s.CompareTo(max) < 0).ToList(); // a1, a10, a3
    		var minElements2 = list.Where(s => NaturalComparer.Compare(s, max) < 0).ToList(); // a1, a3
    	}
    }
    Ответ написан
    Комментировать
  • Книги по Windows Forms на C#. Какие?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Вы правильно увидели. Новых книг по WinForms нет, потому что есть WPF. Изучайте его. Он быстрее, лучше, мощнее. WinForms не развивается дальше, в отличии от WPF.
    Единственно, если вы думаете делать программы не на Windows, а на Линукс, то да - WinForms. Но если под винду, то WPF.
    Ответ написан
    9 комментариев
  • С#. Почему локальным переменным, определенным в методе, необходимо задавать начальное значение, а полям класса можно не задавать?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Потому что поле класса автоматически инициализируется дефолтным значением перед выполнением конструктора.
    class Test
    {
        public int a = 10;
        public int b; // автоматически будет 0
        public int с; // тут сначала будет 0, потом в конструкторе станет 20
        public Test()
        {
            c = 20;
        }
    }
    Ответ написан
    Комментировать
  • Windows Presentation Foundation мертв?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Ваши данные устарели. Ещё два года назад были об этом разговоры, но сейчас WPF жив и здравствует. Несколько лет назад Microsoft развивала ASP.NET и UWP, ресурсов на развитие WPF не хватало (в принципе, и так был достаточно развит). Но вот в 2014 году появилось обновление WPF (на хабре 1 и 2). И в дальнейшем тоже будет развиваться. Microsoft всё ещё делают ставку именно на WPF, никаких других технологий на смену нет (если не считать UWP, но они далеко не полностью пересекаются).

    Проблемы в WPF есть, конечно же, есть куда расти. Но это был гигантский шаг вперёд после WinForms. А то, что некоторых вещей нет "в коробке", но есть в NuGet - так берите и пользуйтесь! WPF дал удобную платформу, на которой легко добавить то, чего нет.
    Ответ написан
    3 комментария
  • Где оптимальнее размещать методы общего назначения в структуре или классе?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Код:
    class MyClass
    {
        public void Test()
        { }
        public static void TestStatic()
        { }
    }
    
    struct MyStruct
    {
        public void Test()
        { }
        public static void TestStatic()
        { }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            MyClass.TestStatic();
            MyStruct.TestStatic();
    
            var c = new MyClass();
            c.Test();
            var s = new MyStruct();
            s.Test();
        }
    }


    IL-код:
    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      // Code size       43 (0x2b)
      .maxstack  1
      .locals init ([0] class ClassOrStructApp.MyClass c,
               [1] valuetype ClassOrStructApp.MyStruct s)
      IL_0000:  nop
      IL_0001:  call       void ClassOrStructApp.MyClass::TestStatic()
      IL_0006:  nop
      IL_0007:  call       void ClassOrStructApp.MyStruct::TestStatic()
      IL_000c:  nop
      IL_000d:  newobj     instance void ClassOrStructApp.MyClass::.ctor()
      IL_0012:  stloc.0
      IL_0013:  ldloc.0
      IL_0014:  callvirt   instance void ClassOrStructApp.MyClass::Test()
      IL_0019:  nop
      IL_001a:  ldloca.s   s
      IL_001c:  initobj    ClassOrStructApp.MyStruct
      IL_0022:  ldloca.s   s
      IL_0024:  call       instance void ClassOrStructApp.MyStruct::Test()
      IL_0029:  nop
      IL_002a:  ret
    } // end of method Program::Main


    Анализ: Вызовы статического метода класса или структуры идентичны. Вызовы обычных методов класса и структуры похожи, но не идентичны. Дополнительно, для создания объекта его нужно создавать в куче и собирать коллектором мусора.

    Результат: если вызывается статический метод, то разницы нет. Если метод обычный, не статический, то некоторая разница имеется, но в основном - в том, что объект нужно будет собирать ненужный объект в GC. Но в данном случае объект будет в нулевом поколении, сборка такого объекта почти бесплатна.

    Вывод: используйте статические классы для хелперов.
    Ответ написан
    2 комментария
  • Как по требованию обновлять ListBox (WPF)?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Во-первых, лучше использовать ItemsSource, а не DataContext. А во-вторых, вместо List взять ObservableCollection.
    Ответ написан
    3 комментария
  • Как переопределить Object.GetHashCode()?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    если у вас ключ является строкой, то возьмите хэш строки:
    class Test
    {
        public string Name;
    
        public override int GetHashCode()
        {
             return Name.GetHashCode();
        }
    }


    Но обычно нужно ещё и Equals переопределить.
    Ответ написан
  • Unity: NullReferenceException: Object reference not set to an instance of an object в чём ошибка?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Я думаю, проблема как раз в том, что у вас разные компоненты у разных объектов - у зомби пытаетесь получить доступ к объекту скрипта жизней, но этот скрипт у персонажа, а не у зомби, поэтому playerHealth = GetComponent(); даст null.

    Вы неправильно пытаетесь связываться с разными объектами. В одном объекте не нужно иметь ссылку на объект другого персонажа. А как же тогда уменьшить жизни? Через событие - у вас есть OnTriggerEnter2D - вот в нём есть ссылка на тот объект, с которым только что столкнулся, вот в нём и нужно выбивать жизни:
    void OnTriggerEnter2D(Collider2D col)
    {
        if (col.gameObject.name == "Character")
        {
            var pers = col.gameObject.GetComponent<HealthCharacter>();
            if (pers != null)
            {
                pers.TakeDamage(attackDamage);
            }
        }
    }

    И не надо проверять объект по его имени (я имею в виду код if (col.gameObject.name == "Character") ), в Юнити есть прекрасная штука - теги. Создайте тег Enemy и тег Hero (или как у вас там персонаж называется), и вот по ним проверяйте - с ним столкнулся, или нет.
    Ответ написан
  • Как развиваться новичку в c# и направлении разработки приложений под win?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Недавно я отвечал на другой вопрос: Программа «Информационное окно» для компьютеров в локальной сети?, почитайте, что я отвечал.

    Возьмите маленькую задачку, и постарайтесь не просто сделать программу, но сделать правильно, используя различные технологии разработки. Для начала сделайте программку, которую можно сделать за недельку, потому что нанопрограммки за день вас уже не научат сильно.
    Сделайте пару UserControl-ов - вы научитесь разделять большую программу на маленькие части.
    Код этих юзер-контролов используйте с помощью вьюмодели, не пишите код в xaml.cs-файле.
    Освойте свойства зависимости - что это такое, и когда они нужны, а когда можно и без них. Без них сделать хороший юзер-контрол не получится.
    Создавайте события для связи между разными юзер-контролами, если по другому не обойтись.
    Используйте LINQ.
    Установите Resharper (бесплатный EAP).
    Используйте Git, даже для своего минипроекта. Научитесь разделять задачу на подзадачи, и каждую подзадачу комитьте. (Вполне нормально делать несколько коммитов в день)
    Читайте книги, статьи. Каждый день читайте хабрахабр.
    Ни дня без строчки кода :) Есть только один способ стать хорошим программистом - много писать кода.

    Мой ответ получился не про то, что делать прямо сейчас, а про то, как развиваться дальше. Многие из советов относятся не к разработке Win-приложений, и даже не к C#. Но уже через полгода вы станете заметно лучшим программистом.
    Если вы не знаете, какую задачу начать сделать - спросите, подскажем.
    Ответ написан
  • В каком порядке учить c# по тролсену?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Я бы рекомендовал читать вначале всю первую половину (части I - V, главы 1 - 18), а затем читать те остальные части, которые интереснее и важнее для вас.
    Первые пять частей - основы самого языка c# и основы .net. Это пригодится всегда и в любом типе проектов. Разве что, пятая часть не так важна, как предыдущие части, но в любом случае - осознание в пятой части даёт понимание того, как шарп работает вообще.
    А вот в остальных частях рассматриваются конкретные технологии - работа с БД и сетевые программы, работа с оконными приложениями, и создание сайтов.

    В части VI рассматриваются три подхода работы с БД, каждый из них нужен для изучения, хотя использовать вы будете EF (или LINQ to SQL, который в книге не рассматривается). Также в разделе рассматривается работа с сетевым программированием - как передать денные из одной программы в другую (или из двух экземпляров одной программы). Если это вам сейчас не так важно, то вы можете для начала изучить WPF и/или ASP.NET, а потом вернуться к этому разделу.

    Раздел VII рассказывает об оконных программах. Забудьте про WinForms, и используйте WPF - он намного мощнее и удобнее. Единственно, для чего может пригодиться WinForms - это поддержка старых проектов, а также кросс-платформенные платформы (хотя там тоже есть варианты с WPF). В книге не рассмотрены паттерны проектирования, поэтому отдельно изучите паттерн MVVM. Даже сейчас вы не планируете изучать WPF И оконные Win-приложения, то всё равно потратьте время - какой же вы программист, который не может сделать калькулятор? :)

    Раздел VIII рассказывает о создании сайтов с помощью ASP.NET. Но этот раздел самый бесполезный из всей книги - сейчас сайты на ASP.NET делаются по другому, чем автор описывает - гораздо лучше использовать ASP.NET MVC (а вскоре выйдет релиз ASP.NET MVC 5.0, где многое также изменится). Хотя этот раздел всё-равно полезный, благо, не очень большой.
    Ответ написан
    5 комментариев
  • Что выбрать для игр?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Если вы уже знаете c++, то подумайте о UnrealEngine.
    Если вы хотите ещё освоить c#, то Unity3d - тоже прекрасный вариант.
    Xamarin - это платформа для разработки кросс-платформенных программ, пишется на c#. Обычно используется для не-игровых программ, а игровые лучше делать в юнити.
    Для игр попроще можно использовать платформы типа Marmalade или Corona, да даже GameMaker.
    Также может быть отличным решением делать программу на html+css+js с помощью Cordova.

    UnrealEngine и Unity3d примерно одинаковы по мощности, традиционно UnrealEngine имеет лучшую графику Unity3d, но язык c# в Unity3d удобнее и заметно проще, чем в UnrealEngine.

    Лично моё мнение - начните работать с Unity3d. Мощный, быстрый, имеет хорошее сообщество, быстро развивается. Плюс, c# - это плюс :)

    Насколько хорошо вы знаете программирование вообще и c++/c# в частности? Поищите здесь вопросы, с чего начать изучать языки.

    Какие движки/фрейворки я буду использовать в дальнейшем?
    А вот это вопрос к вам, а не к нам :)
    Ответ написан
    Комментировать
  • Доступ из другого потока, зависание Invoke, как решить?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Вопрос в том, в каком потоке вызывается эта функция.
    Вместо this.Invoke поставьте Dispatcher.BeginInvoke.
    Ответ написан
    Комментировать
  • Как с listBox1.SelectedItem сделать масcив?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    // получаем строку с элементами
    string Str1 = listBox1.SelectedItem.ToString();
    // разделяем строку в массив строк по символу "пробел"
    var strings = Str1.Split(' ');
    // Преобразуем все строки в числа
    var items = strings.Select(double.Parse);
    // Находим максимальный элемент
    var max = items.Max();
    // Ищем индекс максимального элемента
    var maxIndex = Array.IndexOf(items, max);
    
    // Можно сократить запись:
    string Str = listBox1.SelectedItem.ToString();
    var items = Str.Split(' ').Select(double.Parse).ToArray();
    var maxIndex = Array.IndexOf(items, items.Max());
    Ответ написан
    Комментировать
  • C# вернуть массив из класса?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Во-первых, не нужно пересоздавать список в цикле. Вы уже создали список в начале метода - вот его и используйте, иначе в каждом найденном элементе xml-документа затираются ранее найденные элементы (разве что вы так и хотите сделать, и то - лучше сделать это по другому). Уберите list = new List(); в цикле.

    Во-вторых, вы уверены, что "Ссылка на объект не указывает на экземпляр объекта" - проблема с DbConf[0], а не с logger? Или, скорее, проблема в самом методе. Например, в n.SelectSingleNode("server").InnerText - и правда есть элемент "server"?. Потому что этот код метода выглядит как правильный.
    Поставьте брейкпоинт в метод, и посмотрите по шагам, где именно возникает исключение.

    Ну и в-третьих, названия методов принято называть, начиная с глагола. Метод (функция) - это действие с данным, а не данные. Назовите метод ReadXml().

    UPD.
    но как мне обратиться из любого места программы к данным?

    Сколько у вас конфигов? Больше одного? ведь у вас список, значит, нужно выбирать конкретный конфиг:

    var configs = DbConfig.GetDbConf();
    Console.WriteLine("{0} {1}", c[0].Server, c[0].Port);


    А если вы знаете имя сервера, то используйте словарь вместо списка:
    public static Dictionary<string, DbConf> GetDbConf()
    {
    	try
    	{
    		var configs = new Dictionary<string, DbConf>();
    		
    		// ...
    
    		foreach (XmlNode n in xml.SelectNodes(Properties.Settings.Default.setting_node))
    		{
    			string server = n.SelectSingleNode("server").InnerText;
    			configs.Add(server, new DbConf
    			{
    				Server = server,
    				Port = n.SelectSingleNode("port").InnerText,
    				User = n.SelectSingleNode("user_id").InnerText,
    				Pass = n.SelectSingleNode("password").InnerText,
    				Db = n.SelectSingleNode("database").InnerText
    			});
    		};
    		return list;
    	}
    	catch (Exception msg)
    	{
    		logger.Debug(msg);
    		return null;
    	}
    }

    var configs = DbConfig.GetDbConf();
    var serverName = "localhost";
    var config = configs[serverName];
    Console.WriteLine("{0} {1}", config.Server, config.Port);


    И сделайте в классе более типизированные поля - Port и User можно сделать int (тогда уж не User, а UserId).
    Ответ написан
    Комментировать
  • Как правильно инициализировать данные в Unity C#?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Это как раз тот случай, когда ваш код нужно писать в Awake(), а не в Start(). Awake() запускается сразу после запуска игры (для каждого объекта), потом происходит первоначальная настройка всех объектов, и после этого запускается Start() (опять же - для каждого объекта). Юнити не указывает, в каком порядке будут инициализированы объекты сцены. Поэтому, в Awake() пишите код, связанный с этим самим объектом, а код, связанный с другими объектами, пишите в Start().
    Ответ написан
    3 комментария
  • Программа "Информационное окно" для компьютеров в локальной сети?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Если вы хотите не только сделать проект для портфолио, но и научиться, то вам нужно узнать, как сейчас делают промышленные проекты.

    Во-первых, это WPF, никакого WebForms. Научитесь использовать привязки (bindings).
    Во-вторых, обязательно освойте MVVM - этот паттерн заметно улучшает архитектуру проекта, особенно большого.
    В-третьих, ознакомьтесь (а лучше - попробуйте) с паттернами проектирования (читайте "банду четырёх").
    В-четвёртых, научитесь использовать системы контроля версий - Git (можно и SVN может пригодиться). Заодно, свой проект выложите на гитхаб.

    Если вы уже неплохо знаете C# в частности и программирование вообще, то настоятельно рекомендую книгу Эндрю Троелсена "Язык программирования C# 5.0 и платформа .NET 4.5". Это не учебник по программированию. Это основательнейший труд (более 1300 страниц!) обо всём - о языке C#, о .NET, о WPF, о ASP.NET, о сетевом программировании.

    А о самой программе вам хорошо ответил Антон Федорян.
    Ответ написан
    Комментировать
  • Какой тип данных для работы с двоичной системой счисления существует в C#?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    public struct MyBool
    {
        private byte _val;
    
        public byte Value
        {
            get { return _val; }
            set { _val = (byte)(value == 0 ? 0 : 1); }
        }
    
        public MyBool(int a)
        {
            _val = (byte)(a == 0 ? 0 : 1);
        }
    
        public override string ToString()
        {
            return _val == 0 ? "0" : "1";
        }
    
        public override int GetHashCode()
        {
            return _val;
        }
    
        public override bool Equals(object obj)
        {
            return _val == ((MyBool)obj).Value;
        }
    
        public static implicit operator MyBool(int a)
        {
            return new MyBool(a);
        }
    
        public static implicit operator int(MyBool a)
        {
            return a._val;
        }
    }


    MyBool[] arr1 = {1, 0, 1, 1, 0, 0, 0, 1};
    MyBool[] arr2 = {1, 0, 2, 3, 0, 0, 0, -5}; 
    // автоматически преобразуется в {1, 0, 1, 1, 0, 0, 0, 1}
    // во всех си-подобных языках не-ноль - это истина
    Ответ написан
    Комментировать
  • C# WPF нажатие кнопки при нажатии enter?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    У кнопки есть свойство IsDefault. Поставьте туда истину.
    Ответ написан
    4 комментария