Ответы пользователя по тегу C#
  • Возможно ли связать нынешние знания с вхождением в IT сферу?

    @majstar_Zubr
    C++, C#, gamedev
    UPDATED:

    Lampapuc, вы знаете, скорее всего срока нет, потому что никому кроме вас этого не нужно. Ну, потратите год- два, работодателю все равно, лишь бы основную работу исполняли. Благодаря плагину оптимизируете свою работу, значит больше сделаете за рабочий день. Ну, и если нужен будет какой-то плагин потом сделать другой , то никаких программистов нанимать не надо - есть же свой парень. А это открывает дверь для таких замечательных ситуаций, как разработка ненужных плагинов, потому что "заказчик" ничем не рискует, выгорание, потому что нужно работать на двух должностях по факту.

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

    только тогда стоит браться за такую задачу на вашем месте.

    А это ещё только цветочки, ведь написать плагин (а вернее, первую его версию) это только 20% от аппетита, который приходит во время еды:
    - а кто будет им пользоваться?
    - а кто будет тестировать?
    - а кто будет писать документацию / отвечать на вопросы / учить им пользоваться?
    - а кто будет вносить изменения, за какое время и на каких условиях?
    Учитывая, что процессов таких в вашей компании нет, а жертвуют они практически ничем (новым работником, который студент = будет легко прогибаться на любые хотелки), то по всей видимости, этим всем будете заниматься вы. Проблемы в этом никакой, только если у вас должность содержит слова "инженер-программист". Либо вы нацелены ее получить, в другой компании, например. Иначе - нет смысла ухудшать себе карьерные перспективы и условия труда.

    А если бы у вас это было в виде хобби, то вы бы и вопроса тогда не задавали.

    Сроки про год - два это не шутка, но это сроки по знакомству с составляющими C#, теоритической базой, а так же практикой использования C# / программирования / разработкой ПО в целом, т.к. со всеми концепциями у вас будет знакомство в первый раз. Скорее всего, платить такой налог ради одного плагина не стоит.

    Поэтому, хорошо подумайте, вам нужно все хорошо взвесить.

    ---

    Автоматизация в revit реализована с помощью Python. Знание о том, что какая-то часть revit написана на C#, и знание самого C# вам никак не помогут достичь целей.

    Автоматизация процессов на *nix так же, можно сказать, значимую часть реализуют на Python.

    Пока будете разбираться с Python, разберётесь со своими желаниями и дальнейшими планами.
    Ответ написан
  • Какие есть компиляторы для C#?

    @majstar_Zubr
    C++, C#, gamedev
    Ещё есть транслятор MSIL -> LLVM и биндинги под C#
    Ответ написан
    Комментировать
  • Как использовать (в чем смысл) sealed?

    @majstar_Zubr
    C++, C#, gamedev
    Sealed переводится как "запечатанный, герметизированный". Запечатывается что именно?

    1) Применение к объявлению класса. Первый пример показывает контекст применения ключевого слова. Функционал наследования запечатывается на первом же уровне наследования. В вашем контрпример не предоставляется новой информации для компилятора, поскольку на моменте компиляции компилятор сам может прийти к выводу, нужно ли при хранении объектов класса использовать указатель на таблицу виртуальных функций. Поэтому там слово sealed синтаксически верно, но лексически бесполезно.

    2) Применение к объявлению члену класса. Запечатывание подразумевает наличие кое-чего, что можно запечатать. Именно - функционал наследования. Если вам нужно запечатать функционал наследования на каком-то уровне, вы это делаете. Если вы пытаетесь запечатать что-то на
    нулевом
    уровне базового класса, то это в терминологии C# это невыражаемая мысль. Вы не должны использовать в таком случае наследование вообще (не объявлять virtual). Такую мысль могло бы выразить ключевое слово final (С++), но в C# его нет, в нём ООП используется немного в другом в контексте (где, грубо говоря, типы могут быть manged и unmanaged, и у программиста нет полного контроля над sizeof объектов типа).

    Именно поэтому поведение реализовано как реализовано и
    When applied to a method or property, the sealed modifier must always be used with override.


    Почему запечатывание свойства я могу применить только ко второму классу?

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

    @majstar_Zubr
    C++, C#, gamedev
    Нужно засетапить Clock mode и хорошо приглядеться к докам
    Ответ написан
    Комментировать
  • Как в C# реализованы: uniform инициализация, список инициализации в конструкторе, и дружественные функции и классы?

    @majstar_Zubr
    C++, C#, gamedev
    UPDATED:

    Задачу реализации дружественной функции можно решить, если целевой класс будет partial:

    using System;
    
    namespace FriendFunctionExample
    {
        public partial class TargetClass
        {
            public TargetClass(int state)
            {
                privateState = state;
            }
    
            private int privateState = int.MaxValue;
            protected int targetNonPublicField = -1;
    
            public string Report() { return $"My protected value is {targetNonPublicField}"; }
            public object NativeInterfaceMethod01() { return new object(); }
            public int NativeInterfaceMethod02() { return 7; }
            public float NativeInterfaceMethod03() { return 3.14f; }
        }
    
    }
    
    
    namespace FriendFunctionExample
    {
    
        interface IExtendedTargetClass
        {
            int PrivateState { get; set; }
            int TargetNonPublicField { get; set; }
        }
    
        public partial class TargetClass : IExtendedTargetClass
        {
            public int PrivateState { get => privateState; set => privateState = value; }
            public int TargetNonPublicField { get => targetNonPublicField; set => targetNonPublicField = value; }
        }
    
        class FriendFunctionHandler
        {
            private IExtendedTargetClass target;
    
            public FriendFunctionHandler(IExtendedTargetClass target)
            {
                this.target = target;
            }
    
            public string DoSomethingAndReport(int number)
            {
                FriendFuncion(number);
                return $"Set target protected value to 42 by friend function;";
            }
    
            private void FriendFuncion(int value) // set new value
            {
                target.TargetNonPublicField = value;
            }
        }
    
        class FriendFunctionExample
        {
            static void Main(string[] args)
            {
                Console.WriteLine(nameof(FriendFunctionExample));
    
                int initValue = 777;
    
                var target = new TargetClass(initValue);
    
                var ffh = new FriendFunctionHandler(target);
    
                Console.WriteLine(target.Report());
                Console.WriteLine(ffh.DoSomethingAndReport(42));
                Console.WriteLine(target.Report());
    
                Console.ReadLine();
            }
        }
    }


    FriendFunctionExample
    My protected value is -1
    Set target protected value to 42 by friend function;
    My protected value is 42


    OLD:

    - свободных функций нет, но это быть статический класс с нужным методом,
    - дружественную функцию можно реализовать через вызов метода расширения, а излишнюю открылось функции закрыть через internal
    Ответ написан
  • Зачем нужны статические(ударение на слово "статические") поля/автоматические статические свойства в классе?

    @majstar_Zubr
    C++, C#, gamedev
    Статическая область памяти инициализируется до начала исполнения точки входа main.

    Статический класс гарантирует существование единственного экземпляра класса.

    Статическое поле позволяет реализовать хранение данных, которые будут существовать вплоть до выхода из функции main.

    Статический конструктор позволяет произвести предварительную инициализацию для класса ещё до создания хотя бы одного экземпляра класса.

    Статические данные, таким образом, можно считать достоянием главного потока, исходного процесса.

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

    Если использование кода не предполагает использование класса в нескольких потоках, то допускается использование "общих" данных в статических полях, но как правило, это рационально только для readonly и const.
    Ответ написан
    Комментировать
  • Методы и функции в C#?

    @majstar_Zubr
    C++, C#, gamedev
    Есть термины функция, процедура, метод в рамках парадигм программирования, но терминология в C# иная.

    В C# нет функций и процедур, есть только методы и делегаты.
    Лямбда-выражения, в зависимости от контекста, "под капотом" приводятся к анонимным делегатам с телом или к Func, Predicate, Action.
    Все утыкается в объектную модель, которую поддерживает абстрактная машина языка C#.
    Единицей трансляции является класс, и свободных функций в namespace быть не может, так же как и указателей на функцию в принципе - вместо указателей на функцию в C# используются делегаты. Делегат реализован как абстрактный класс, это позволило реализовать типобезопасные ссылки на методы, которые можно складывать и вычитать, позволило удобно реализовать асинхронность.

    Делегат указывает только лишь на сигнатуру метода. Но предполагается, что объект, у которого вызывается метод через делегат, является экземпляром класса, который имеет такую же сигнатуру, как и делегат.

    В C# нет понятия функции как объекта, функцию нельзя просто так создать. Вообще можно, но прежде чем её использовать, её нужно будет скомпилировать, но она будет в любом случае в каком-то классе, и она будет методом этого класса; и чтобы методы вызвать, сначала надо получить ссылку на экземпляр класса.
    Ответ написан
    Комментировать
  • (windows. forms) Почему не правильно вычисляет?

    @majstar_Zubr
    C++, C#, gamedev
    получается 3, потом от 3,6 отнимается 3, должно получатся 0,6


    В общем случае - нет, не должно.

    А вот если округлять правильно
    Math.Round(double_num,2); , то с указанной точностью всё гарантируется.
    Ответ написан
    6 комментариев
  • Какой язык программирования можно изучать одновременно с C#?

    @majstar_Zubr
    C++, C#, gamedev
    Чтобы знания не превратилась в кашу, их нужно не просто полностью систематизировать, но и закрепить опытом, как и какие задачи в рамках языка решать не надо, а как можно.
    Для этого нужно "изучить" C#, нужно не просто "изучить" синтаксис, а ещё устройство .net, CIL и сборщика мусора.
    Сначала научитесь проектировать и кодировать на языке, проектировать и кодировать с помощью языка будете уже после того, как научить решать практически любые задачи хотя бы на одном.
    Иначе вы просто растянете промежуток времени, когда вы ни рыба, ни мясо в двух языках.
    Ответ написан
    Комментировать
  • Почему кнопка работает со 2 раза?

    @majstar_Zubr
    C++, C#, gamedev
    На местах строк "bol = false;" "bol = true;" должно быть "bol = !bol;"
    Ответ написан
  • Можно ли сделать индексаторы динамической длиный?

    @majstar_Zubr
    C++, C#, gamedev
    class People{
    List<Person> data = new List<Person>();
    ...


    + обработка ошибок
    Ответ написан
    Комментировать
  • Аналог Eval из JS в C#?

    @majstar_Zubr
    C++, C#, gamedev
    Ответ написан
    Комментировать
  • Как принудительно запустить программу от имени администратора?

    @majstar_Zubr
    C++, C#, gamedev
    Clickonce

    https://docs.microsoft.com/en-us/visualstudio/depl...

    Файл манифеста:

    https://docs.microsoft.com/en-us/dotnet/csharp/lan...

    Или в VS добавить ресурс - манифест файл - там
    <requestedExecutionLevel level="requireAdministrator" uiAccess="true" />


    Powershell:

    runas /user:"имя_компьютера\имя_уч_зап_админа" "C:\путь\program.exe"
    Ответ написан
    Комментировать
  • Как упростить монотонный код на C#?

    @majstar_Zubr
    C++, C#, gamedev
    См. Макконнелл, Совершенный код, глава 18, Табличные методы.
    Ответ написан
    Комментировать
  • Как сделать иерархию классов?

    @majstar_Zubr
    C++, C#, gamedev
    Поднимите свойство в класс-родитель.
    Сделайте виртуальные методы в родителе bool Damage( int damagPoints ), bool Heal (int healthPoints).

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

    Если хотите сделать некоторых конкретных Enemy с особыми свойствами, то сделайте реализации инвариантов также виртуальными. Допустим Slug получает 50% урона и только чётный урон.

    Тогда например Slug:

    new public bool Damage( int damagePoints )
    {
        if (isDamageAcceptable(damagePoints))
        {
            int appliedDamage = Math.Ceiling(damagePoints/2);
            TakeDamage(appliedDamage);
        }
        return isDamageAcceptable(damagePoints);
    }
    
     new protected bool isDamageAcceptable( int damagePoints) => (damagePoints > 0) && (0==damagePoints%2) );


    Обобщение есть согласие наследника наследовать И интерфейс И функциональность. Инвариант может расширяться, если он сужается, то это значит, что наследование не подходит для данного класса.

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

    Если речь о том, что у не у всех задуманных Enemy может быть здоровье, то вам нужно либо менять модель отношения классов и пересмотреть абстракции, либо использовать композицию вместо наследования.
    Ответ написан
    Комментировать
  • Почему переопределение в C# работает так?

    @majstar_Zubr
    C++, C#, gamedev
    public class Class2
        {
            public string GetVal(int a, int b)
            {
                return "base";
            }
    
            public override string ToString()
            {
                return "_Class2_";
            }
        }


    public class Class3 : Class2
        {
    
            
            public string GetVal(int a, int b, bool defaultpar = true)
            {
                return "child with bool";
            }
    
            public new string GetVal(int a, int b)
            {
                return "child";
            }
    
            public override string ToString()
            {
                return "_Class3_";
            }
        }


    class Program
        {
            static void Main(string[] args)
            {
                Class2 obj_reference_c2 = new Class2();
                Class3 obj_reference_c3 = new Class3();
                Class2 obj_reference_assigned = obj_reference_c3;
                Class2 obj_reference_casted = (Class2)obj_reference_c3;
    
                Console.WriteLine($"Вызов - {obj_reference_c2} c параметрами 1, 2 : {obj_reference_c2.GetVal(1, 2)}");
                Console.WriteLine($"Вызов - {obj_reference_c3} c параметрами 1, 2 : {obj_reference_c3.GetVal(1, 2)}");
                Console.WriteLine($"Вызов {obj_reference_c3} c параметрами 1, 2 true: {obj_reference_c3.GetVal(1, 2, true)}");
    
                Console.WriteLine($"Вызов Class3 присвоенного по ссылке типа Class2 - {obj_reference_assigned} c параметрами 1, 2: {obj_reference_assigned.GetVal(1, 2)}");
                Console.WriteLine($"Вызов Class3 приведенного к типу Class2 - {obj_reference_casted} c параметрами 1, 2: {obj_reference_casted.GetVal(1, 2)}");
    
                /*      
                Вариант 1: в Class3 метод public string GetVal(int a, int b) {return "child";} закомментирован
    
                    Вызов - _Class2_ c параметрами 1, 2 : base
                    Вызов - _Class3_ c параметрами 1, 2 : child with bool
                    Вызов _Class3_ c параметрами 1, 2 true: child with bool
                    Вызов Class3 присвоенного по ссылке типа Class2 - _Class3_ c параметрами 1, 2: base
                    Вызов Class3 приведенного к типу Class2 - _Class3_ c параметрами 1, 2: base
    
                 */
    
                /*
                  Вариант 2: в Class3 метод public string GetVal(int a, int b) {return "child";} существует и прячет унаследованный член Class2.GetVal(int,int)
                
                    Вызов - _Class2_ c параметрами 1, 2 : base
                    Вызов - _Class3_ c параметрами 1, 2 : child
                    Вызов _Class3_ c параметрами 1, 2 true: child with bool
                    Вызов Class3 присвоенного по ссылке типа Class2 - _Class3_ c параметрами 1, 2: base
                    Вызов Class3 приведенного к типу Class2 - _Class3_ c параметрами 1, 2: base
    
                    в подобном случае требуется явно указывать в объявлении модификатор new:
                       public new string GetVal(int a, int b) {return "child";}
                 */
                Console.ReadLine();
            }
        }


    В вашем примере 1 не происходит перегрузка метода базового класса.
    Метод базового класса можно перекрыть ( public new string Foo() ) или переопределить, если базовый метод виртуальный.

    Перегруженные методы существуют только в одной области видимости, которая в C# ограничена классами.

    С точки зрения .Net, методы с сигнатурами string _ (int,int) и string _ (int,int,bool) разные, но синтаксически, в случае, если в методе string _ (int,int,bool) третий параметр снабжается параметром по умолчанию, не существует явного способа вызова, кроме Named Arguments.

    public class Class2
        {
            public string GetVal(int a, int b)
            {
                return "base";
            }
    
            public override string ToString()
            {
                return "_Class2_";
            }
        }
    
        public class Class3 : Class2
        {
            public new string GetVal(int a, int b)
            {
                return "child";
            }
    
            public string GetVal(int A, int B, bool defaultpar = true)
            {
                return "child with bool";
            }
    
            public override string ToString()
            {
                return "_Class3_";
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Class2 obj_reference_c2 = new Class2();
                Class3 obj_reference_c3 = new Class3();
                Class2 obj_reference_assigned = obj_reference_c3;
                Class2 obj_reference_casted = (Class2)obj_reference_c3;
    
                Console.WriteLine($"Вызов - {obj_reference_c2} c параметрами 1, 2 : {obj_reference_c2.GetVal(1, 2)}");
                Console.WriteLine($"Вызов - {obj_reference_c3} c параметрами 1, 2 : {obj_reference_c3.GetVal(1, 2)}");
                Console.WriteLine($"Вызов - {obj_reference_c3} c параметрами 1, 2 : {obj_reference_c3.GetVal(A:1, B:2)}");
                Console.WriteLine($"Вызов {obj_reference_c3} c параметрами 1, 2 true: {obj_reference_c3.GetVal(1, 2, true)}");
    
                Console.WriteLine($"Вызов Class3 присвоенного по ссылке типа Class2 - {obj_reference_assigned} c параметрами 1, 2: {obj_reference_assigned.GetVal(1, 2)}");
                Console.WriteLine($"Вызов Class3 приведенного к типу Class2 - {obj_reference_casted} c параметрами 1, 2: {obj_reference_casted.GetVal(1, 2)}");
    
                /*
                   
                Вариант 1Б: в Class3 метод public string GetVal(int a, int b) {return "child";} закомментирован
    
                    Вызов - _Class2_ c параметрами 1, 2 : base
                    Вызов - _Class3_ c параметрами 1, 2 : child with bool
                    Вызов - _Class3_ c параметрами 1, 2 : child with bool
                    Вызов _Class3_ c параметрами 1, 2 true: child with bool
                    Вызов Class3 присвоенного по ссылке типа Class2 - _Class3_ c параметрами 1, 2: base
                    Вызов Class3 приведенного к типу Class2 - _Class3_ c параметрами 1, 2: base
    
                 */
    
                /*
    
               Вариант 2Б: в Class3 метод public string GetVal(int a, int b) {return "child";} существует и прячет базовый
    
                    Вызов - _Class2_ c параметрами 1, 2 : base
                    Вызов - _Class3_ c параметрами 1, 2 : child
                    Вызов - _Class3_ c параметрами 1, 2 : child with bool
                    Вызов _Class3_ c параметрами 1, 2 true: child with bool
                    Вызов Class3 присвоенного по ссылке типа Class2 - _Class3_ c параметрами 1, 2: base
                    Вызов Class3 приведенного к типу Class2 - _Class3_ c параметрами 1, 2: base
    
                */
    
                Console.ReadLine();
            }
        }


    Данный пример не очень показателен с точки зрения использования named arguments.
    Для этого потребуется несколько аргументов со значениями по умолчанию.

    Хотя я рекомендую никогда не использовать значения по умолчанию, вместо этого стоит делать SOLID классы со специализированными методами и понятным API, а named arguments позволяют фривольно писать код в отрыве от порядка аргументов в сигнатуре, хоть задом наперед: c.GetVal( defaultpar: false, B: 42, A: 777);
    Ответ написан
    1 комментарий
  • Если ли готовое решение перевода с big endian в little endian?

    @majstar_Zubr
    C++, C#, gamedev
    Есть готовое кросс-платформенное решение в SDL.

    wiki.libsdl.org/CategoryEndian

    hg.libsdl.org/SDL/file/default/include/SDL_endian.h

    У SDL есть биндинги в частности под C# и python, если с c/c++ не сложилось.
    Ответ написан
    Комментировать