Подготовка к сертификационному экзамену Microsoft 70-483 «Programming in C#»


    Во время подготовки к экзамену номер 70-483 нашел множество разрозненных сайтов с различными ссылками на мануалы, которые мне немного помогли. Но, что помогло мне больше, так это то, что я составил для себя памятку на нескольких страницах, выдержками из которой и хочу поделиться.
    Целью не является подробное описание C#, целью является освежить в памяти и заострить внимание на некоторых необходимых темах. Если какие-то темы вам незнакомы, то это значит, что у вас есть пробелы, которые необходимо устранить.
    Раскрывать вопросы тестирования я не могу (да и не помню я уже их), но, если многие из перечисленных ниже нюансов, трюков и тонкостей, помогут вам, то вы на меня не обижайтесь (написано с иронией).

    Начнем с простых вещей, о которых часто забывают, но которые часто используют в тестах:
    Для того, чтобы объявить переменную типа int, и присвоить ей сразу значение 0, можно сделать так: var myInt=0; или так int myInt=0;
    Для того, чтобы объявить переменную типа int, и задать сразу ей значение по умолчанию, нужно сделать так: int myInt = new int();

    Explicit and Implicit типизация
    int i = 42; // это explicit типизация – указан тип переменной int
    var i = 42;  // а это уже implicit типизация. Компилятор задает переменной тип исходя из ее значения.
    

    Используйте implicit типизацию при:
    Анонимных типах — var anonymousType = new { Name = «Alex» };
    Получении результата запроса LINQ — var queryExpression = from c in customers where c.Name == «Andrey» select c;
    Использовании complex generic типов — var searchList = new Dictionary();
    Implicit типизация возможна только для локальных переменных.

    Boxing/Unboxing
    Boxing – это конвертация value типа в тип reference
    Unboxing наоборот – конвертация reference типа в value. Для Unboxing-а необходим Cast.
    Boxing/Unboxing копирует значение переменной.
    Boxing с точки зрения скорости вычислений — операция занимающая довольно много процессорных ресурсов.
    Простой пример:
    int i = 123;
    // Следующая строчка упаковывает переменную i (происходит boxing) 
    object o = i;  // object – это тип reference тип, а int – это тип value
    j = (int)o;  // unboxing – распаковка
    

    Интересный пример ошибки:
    double e = 2.718281828459045;
    object o = e; // box
    // int ee = (int)o; // вызовет runtime exception, так как o не может быть распознано как тип int
    int ee = (int)(double)o; // сделает unboxing без ошибки
    

    Еще пример:
    int count=1;
    object countObject=count; // значение count скопировано в переменную countObject – это boxing
    count+=1; // count уже равен 2, а значение countObject все еще 1
    count=(int)countObject; // теперь и count равно 1 – это был unboxing
    

    Оператор ?? называется null-coalescing operator. Он возвращает левое значение, в случае, если оно не равно null, в ином случае правое значение. Пример:
    int? x = null; // здесь int? означает что это Nullable type т.е. что можно объекту присвоить null
    int y = x ?? -1; // В этом случае y равен -1 потому что x равен null
    

    Оператор ?: называется conditional operator. Он возвращает одно из двух значений исходя из булева выражения. Если выражение равно true, то возвращается первое значение, в ином случае — второе. Для примера 2 аналогичных кода:
    if (input<0)  // используя конструкцию if-else
        classify = "negative";
    else
        classify = "positive";
    
    classify = (input < 0) ? "negative" : "positive";  // используя conditional operator ?:
    

    LINQ
    Любой объект, который реализует интерфейс IEnumerable или IQueryable может быть запрошен используя LINQ.
    Можно использовать как orderby … descending так и OrderByDescending
    orderby h.State, h.City – здесь orderby пишется слитно, однако group h by h.State раздельно ( есть вариант записи заглавными буквами GroupBy )
    Predicate – это условие, которое характеризует субъект. Например:
     where i % 2 == 0
    

    Есть 2 варианта записи LINQ ( синтаксис метода/method и синтаксис запроса/query ):
    var data=Enumerable.Range(1,100);
    var method=data.Where(x=>x%2==0).Select(x=>x.ToString());
    var query=from d in data where d%2==0 select d.ToString();
    

    Простые методы LINQ:
    var values=new[]{“A”,”B”,”C”,”B”,”B”,”A”,”B”};
    var distinct=values.Distinct(); // только неуникальные значения
    var first=values.First();
    var firstordef=values.FirstOrDefault();
    var twoval=values.Skip(2).Take(2);
    

    Интересна возможность вместо && использовать where несколько раз. Например:
    var evenNumbers = from i in myArray where i % 2 == 0 where i > 5 select i;
    

    Можно использовать функции в качестве фильтра. Например:
    var evenNumbers = from i in myArray where IsEvenAndGT5(i) select i;
    static bool IsEvenAndGT5(int i)
    {
    return (i % 2 == 0 && i > 5);
    }
    

    Если необходимо выбрать несколько значений, то нужно использовать new { }
    var names = from p in people select new { p.FirstName, p.LastName };
    

    Причем, можно задать даже псевдонимы:
    var names = from p in people select new { First = p.FirstName, Last = p.LastName };
    
    var names = people.Select(p => new { p.FirstName, p.LastName }); // вариант запроса с синтаксисом метода
    

    LINQ deferred execution — до тех пор, пока элемент не вызывается запрос не выполняется. Пример:
    int[] myArray = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
                var evenNumbers = from i in myArray where i % 2 == 0 select i;
                foreach (int i in evenNumbers)
                {
                    Console.WriteLine(i); // выводим результат LINQ запроса
                }
                myArray[1] = 12; // изменяется элемент массива из которого происходит выборка запросом
                foreach (int i in evenNumbers) // здесь еще раз происходит вызов запроса LINQ
                {
                    Console.WriteLine(i); // выводится первым элементом уже 12 а не 2
                }
    // а вот следующий запрос это Immediate Execution. Данные извлекаются сразу
                var evenNumbersCount=(from i in myArray where i % 2 == 0 select i).Count();
    

    Версия сборки состоит из четырех частей: Major, Minor, Build, and Revision

    Для установки сборки в GAC (Global Assembly Cache) необходима утилита Global Assembly Cache tool (Gacutil.exe). В командной строке вводится команда: gacutil –i
    Но необходимо, чтобы сборка была подписана ключом строгого имени с помощью средства SN
    Пример создания ключа: «C:\GACKey\GACkey.snk» sn –k
    Сборка со строгим именем (strong name) состоит из 5-ти частей:Friendly Name, Version, Culture, Public Key Token, and Processor Architecture
    Подписывая Ваши сборки, храните ключ в надежном месте, а разработчикам выдайте открытую часть ключа, что позволит им использовать сборки без полной подписи.
    Выделить открытую часть ключа можно следующей командой:
    Sn.exe –p «ключ.snk» «открытый ключ.snk»

    Так как версия сборки важна в тот момент, когда runtime пытается найти сборку, то вы можете публиковать различные версии одной и той же сборки в GAC и избежать проблем, которые случаются с обычными dll.
    Это называется side-by-side hosting, при котором множество версий одной и той же сборки хостятся одновременно на одном компьютере (начиная с .Net 4).

    Shallow copy — ловушка при копировании массивов
    При копировании объектов ссылочного типа может быть скопирован указатель на значение, а не само значение. Пример:
    Person[] orginal = new Person[1];
    orginal[0] = new Person() { Name = "John" };
    Person[] clone = (Person[])orginal.Clone();
    clone[0].Name = "Mary";  
    // что интересно – теперь и original[0] и clone[0] содержат “Mary” так как массив ссылочного типа
    
    Person[] orginal = new Person[1];
    orginal[0] = new Person() { Name = "John" };
    Person[] clone = (Person[])orginal.Clone();
    clone[0] = new Person() { Name = "Bob" }; 
    // что интересно теперь original[0]=”John” а clone[0]=”Bob”
    // т.к. ссылка на первый элемент массива original была заменена новым созданным элементом
    

    Closures ( замыкания )
    var funcs = new List<Func>();
    for (int i = 0; i < 3; i++)
    {
        funcs.Add(() => i);
    }
    foreach (var f in funcs)
        Console.WriteLine(f());  // Выведет на экран 3 3 3 а не 1 2 3 как ожидается…
    

    Данный результат обусловлен двумя причинами:
    1. при замыканиях осуществляется захват переменных, а не значений переменных и
    2. в приведенном фрагменте кода, существует один экземпляр переменной i, который изменяется на каждой итерации цикла, а не создается новый экземпляр на каждой итерации.

    Исправить данную ситуацию довольно просто:
    var funcs = new List<Func>();
    for (int i = 0; i < 3; ++i)
    {
        int tmp = i;  // создаем временную переменную
        funcs.Add(() => tmp); 
    // при добавлении в List происходит захват значения временной переменной
    }
    foreach (var f in funcs)
        Console.WriteLine(f()); // теперь все в порядке и мы получим 1, 2, 3
    

    Вы директивы компилятора используете? Вот пара директив для примера:
    #region и #endregion – ограничивают какую-то часть кода и разрешают сворачивание/разворачивание
    #define и #undef – define задают true или false соответственно каким-либо значениям
    #error – сгенерирует ошибку

    Пример условия, которое в случае, если сборка в режиме DEBUG выполнит один кусок кода, а в ином случае другой:
    #if DEBUG
    #elif
    #endif

    Что такое PCL? Portable Component Library — это по сути dll, но с возможностями cross platform. То есть можно создать PCL и назначить платформы в которых она будет использоваться ( например: WP8, WinRT, Xamarin… ). По сути, добавление каждой платформы сужает возможности сборки

    PDB это акроним для Program database file
    PDB содержит отладочные данные и сведения о состоянии проекта, позволяющие выполнять последовательную компоновку отладочной конфигурации программы
    Любой имеющий доступ к dll/exe файлу может легко произвести реверс инжиниринг для того, чтобы генерировать исходный код с PDB или без него, используя такие средства, как например, reflector. Так что, предоставление или не предоставление PDB никак не влияет не безопасность кода.

    Implicit и Explicit реализации интерфейса
    Допустим, что у нас есть 2 интерфейса с одинаковым методом:
    interface InterfaceOne
    {
        void InterfaceMethod();
    }
    interface InterfaceTwo
    {
        void InterfaceMethod();
    }
    

    Мы создаем класс, наследуемый от двух интерфейсов и в нем объявляем метод interfaceMethod:
    public class MyClass : InterfaceOne, InterfaceTwo
    {
        public void InterfaceMethod()
        {
            Console.WriteLine("Угадай метод какого интерфейса вызван?");
        }
    }
    

    Сейчас мы использовали Implicit реализацию интерфейса.
    А если мы укажем наименование интерфейса, то это будет Explicit реализация:
    public class MyClass : InterfaceOne, InterfaceTwo
    {
        void InterfaceOne.InterfaceMethod()
        {
       Console.WriteLine("Сейчас легко угадать какого это интерфейса метод, правда?");
        }
        void InterfaceTwo.InterfaceMethod()
        {
       Console.WriteLine("Сейчас легко угадать какого это интерфейса метод, правда?");
        }
    }
    

    В информатике отражение или рефлексия (синоним интроспекция, англ. reflection) означает процесс, во время которого программа может отслеживать и модифицировать собственную структуру и поведение во время выполнения.
    Пример:
    void Method()
    {
    	var horse=new Animal();
    	var type=horse.GetType();
    	var method=type.GetMethod(“Speak”);
    	var value=(string)method.Invoke(horse,null);   // value=”hello”;
    }
    public class Animal
    {
    	public string Speak() { return “hello”; }
    }
    

    При рефлексии сборку можно загрузить различными способами:
    Assembly.LoadFrom() может сделать перенаправление на другую аналогичную сборку
    Assembly.LoadFile() загружает конкретно сборку из файла.
    Assembly.Load() загружает сборку по указанию ее полного имени

    Разница между Convert и Parse методами в том, что Parse принимает только строку как вводное значение, в то время, как Convert может принимать и другие типы данных.
    Разница между Parse/TryParse и Convert в том, что Convert может принимать нулевые значения и не выбрасывает ArgumentNullException.

    Для представления положительной и отрицательной бесконечности в C# имеется две специальные константы: System.Double.NegativeInfinity и System.Double.PositiveInfinity
    NegativeInfinity — Значением этой константы является результат деления отрицательного числа на нуль, также Данная константа возвращается в случае, если результат операции меньше, чем минимальное значение (MinValue).
    PositiveInfinity – результат деления положительного числа на 0. Константа возвращается в случае, если значение больше, чем MaxValue.
    Infinity включает в себя как NegativeInfinity так и PositiveInfinity

    Ключевое слово unchecked используется для подавления проверки переполнения при выполнении арифметических операций и преобразований с данными целого типа. Если среда unchecked удалена, возникает ошибка компиляции. 2 примера:
    unchecked
    {
        int1 = 2147483647 + 10;
    }
    int1 = unchecked(2147483647 + 10);
    

    По умолчанию C# не выбрасывает исключение, если при сужающем/narrowing преобразовании возникает ошибка с int и float типами.
    Для того, чтобы исключение возникало можно использовать ключевое слово checked. Пример:
    checked
    {
    int big = 1000000;
    short small = (short)big;
    }
    

    Также можно в свойствах проекта поставить галочку о возникновении исключения при overflow/underflow

    Форматирование
    Console.WriteLine(somevariable.ToString("c"))  // форматирует в денежный формат
    // например указав somevariable.ToString("C3", new System.Globalization.CultureInfo("fr-FR")) в случае если somevariable=123.4562 получим -123,456 €
    // ToString("d") или ToString("D") форматирует число в виде decimal
    // можно указать число в виде минимального количества символов. Например, указав ("D6") получим из -1234 число -001234 
    DateTime.Now.ToString("D")  
    // в случае, если параметром является дата, форматирует в короткий формат даты = DateTime.Now.ToShortDateString()
    DateTime.Now.ToString("d")  // длинный формат даты
    


    Rethrow exception
    Стек ошибки очищается каждый раз, когда выбрасывается ошибка.
    static string ReadAFile(string fileName) {
        string result = string.Empty;
        try {
            result = File.ReadAllLines(fileName);
        } catch(Exception ex) {
            throw ex; // Это отобразит ReadAFile в StackTrace – не совсем верное решение
            throw;    // Это же отобразит ReadAllLines в StackTrace – лучше использовать такое
        }
    

    Рекомендуется использовать просто throw, так как в таком случае сохранится информация об исходной ошибке.

    Как вариант можно создать свою ошибку — custom exception
    [Serializable()]
    public class YourCustomException : System.Exception
    {
       // конструктор принимает текст как параметр
       public YourCustomException(string msg) : base(msg)
       {
    
       }
    }
    

    И после можно выбрасывать ошибку:
    try
    {
    throw new YourCustomException("Вам нельзя вводить текст в это поле");
    // какой-то код
    }
    catch(YourCustomException e){}
    

    Не следует наследовать от System.ApplicationException. В идее было, что все C# runtime ошибки должны наследоваться от System.Exception, а все custom exceptions от System.ApplicationException. Но в реалии класс System.ApplicationException не используется совсем.

    В блока try/catch/finally — finally выполняется всегда. Только в случае вызова в коде Environment.FailFast(String) или FailFast(String, Exception), которые прерывают текущий процесс, в случае каких-либо критических повреждений в работе приложения, выполнение программы будет прервано и finally не будет выполнено.

    CodeDOM – это набор классов, которые позволяют генерировать код.
    Класс System.CodeDom.CodeCompileUnit – это класс верхнего топ-уровня, контейнер для всех объектов в генерируемом классе.
    Класс System.CodeDom.CodeDOMProvider генерирует класс файла на C#, VB или JScript.

    Структуры как и классы могут иметь методы, свойства, конструкторы и др.
    Структуры в отличие от классов не могут содержать деструкторы ( фактически деструкторы это Finalize методы ~ИмяКласса которые позволяют уничтожить объект )
    Нельзя объявить пустой конструктор для структуры.
    Также структуры не могут иметь иерархии наследования (для экономии памяти). В C# структуры запечатаны — implicitly sealed. Что означает, что наследовать от структуры нельзя.
    Структуры – это value тип данных = хранится в стеке.
    Классы – это reference тип данных = хранится в куче ( heap ).
    В C# к Value типу данных относятся структуры и перечисления (structs и enumerations).
    Структуры в свою очередь делятся на подкатегории: числовой тип (целочисленный — integral types, с плавающей точкой — floating-point types, 128-и разрядный decimals), булев тип (bool) и пользовательские структуры.
    Перечисления это набор типов, объявленный с помощью ключевого слова enum.
    У value типа данных есть ограничения. Вы не можете наследовать от value типа, а также value тип не может содержать в себе значение null.
    enum Months {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sept, Oct, Nov, Dec};
    // можно использовать не int а другой числовой тип для enum
    enum Months : byte {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sept, Oct, Nov, Dec};
    
    string name = Enum.GetName(typeof(Months), 8);
    Console.WriteLine("Восьмой месяц в enum это " + name);
    
    Console.WriteLine("Числовые значения Months enum:");
    foreach (int values in Enum.GetValues(typeof(Months)))
    {
    Console.WriteLine(values);
    }
    

    Класс Interlocked — Предоставляет атомарные операции для переменных, общедоступных нескольким потокам ( операции Decrement(Int), Increment(Int), Add(Int, Int) ) Значение переменной будет изменено одновременно для всех потоков.
    Метод CompareExchange — сравнивает два значения на равенство и, если они равны, заменяет одно из значений.
    Interlocked.CompareExchange(ref value, newvalue, comparevalue)
    

    Метод Exchange — задает переменную указанным значением — как атомарная операция и возвращает исходное значение. Пример:
    if (Interlocked.Exchange(ref isInUse, 1) ==0){
    // какой-то код
     }
    

    Параметры, передаваемые функциям
    static int CalculateBMI(int weight, int height)
        {
            return (weight * 703) / (height * height);
        }
    

    Стандартно функция вызывается так: CalculateBMI(123, 64);
    Если не помнить порядок, то можно вызывать функцию, указывая названия:
    CalculateBMI(weight: 123, height: 64);
    CalculateBMI(height: 64, weight: 123);
    

    Можно сперва указать параметр по порядку, а затем по имени
    CalculateBMI(123, height: 64);
    

    Но нельзя указывать сперва параметр по имени, а затем по порядку ( вызовет ошибку )
    //CalculateBMI(weight: 123, 64);
    

    Можно указывать значения для параметров по умолчанию и вызывать после функцию без указания этих параметров:
    public void ExampleMethod(int required, string optionalstr = "default string", int optionalint = 10)
    

    Использование StringWriter и StringReader для записи и чтения строк
    	    StringWriter strwtr = new StringWriter();
    	    for(int i=0; i < 10; i++)
    	    strwtr.WriteLine("This is i: " + i);
    	  	  
    	    StringReader strrdr = new StringReader(strwtr.ToString());
    	    // Сейчас читаем из StringReader.
    	    string str = strrdr.ReadLine();
    	    while(str != null) {
    	    str = strrdr.ReadLine();
    	    Console.WriteLine(str);
    

    Сравнение Generics и ArrayList
    var objects=new ArrayList();
    objects.Add(1);
    objects.Add(2);
    objects.Add(“three”); // ArrayList принимает различные типы дынных
    
    var list=new List<int>();
    list.Add(1);
    list.Add(2);
    list.Add(“three”); 
    // последнее непозволительно, так как generic коллекция в данном случае принимает только int тип данных
    

    Regex ( регулярные выражения )
    Пример IsMatch:
     if (Regex.IsMatch(phone, @"^\d{3}-\d{4}$"))
    

    Matches — Ищет во входной строке все вхождения регулярного выражения и возвращает все соответствия:
          string pattern = @"\b\w+es\b";
          Regex rgx = new Regex(pattern);
          string sentence = "Who writes these notes?";
          foreach (Match match in rgx.Matches(sentence))
          Console.WriteLine("Found '{0}' at position {1}",  match.Value, match.Index);
    

    Match – работает точно так же как и Matches, но ищет только первое совпадение
    Split — Разделяет входную строку в массив подстрок в позициях, определенных соответствием регулярного выражения.
    string input = «plum-pear»;
    string pattern = "(-)";
    string[] substrings = Regex.Split(input, pattern);
    

    Replace — В указанной входной строке заменяет все строки, соответствующие шаблону регулярного выражения, указанной строкой замены.
    ^ — начало строки $ — конец строки. – какой-либо символ
    * — повторения предыдущего 0 или несколько раз
    + — повторение предыдущего 1 или несколько раз
    ? – повторение предыдущего 0 или 1 раз
    [abc] – какой-то из символов a,b или c [^abc] – какой-то из символов кроме этих [a-z] – символы от и до [^a-z] – символы кроме от и до
    {n} – совпадение n повторений {n,} – совпадение от n до бесконечности {n,m} – совпадение от n и до m раз
    \d – число \D – не число \s – пробел, таб и т.п. \S – не пробел

    Немного «вредных» советов


    Несмотря на запрет распространения информации об экзамене, при поиске в сети вполне можно найти дампы (сливы информации по вопросам) в частности и к этому экзамену. Стоит ли ими пользоваться и насколько сильно они могут помочь в сдаче экзамена? Даже судя по записям в блогах, пользуются ими многие.

    На мой взгляд, зацикливаться на дампах не стоит. Например, потому что они содержат в себе множество ошибок. Также, следует учесть то, что вопросы время от времени вопросы заменяются. Можно ли смухлевать при сдаче? Пожалуй, немного повезти с вопросами может, но ведь для нас важна не бумажка, а владение языком, правда?
    Довольно легальным способом найти примеры вопросов может быть ознакомление с вопросами из книг: «MCSD Certification Toolkit Exam 70-483 Programming in C#» и «Wouter de Kort Programming in C# Exam Ref 70-483». Книги на английском (как собственно и сам экзамен) и могут помочь вам прокачать свои знания технического английского. Я бы советовал, изучая различные вопросы, обращать внимание не на варианты ответа, а на саму тему вопроса. Таким образом, можно узнать какие-то нюансы языка, а также проработать неизвестные области.
    Из видеокурсов могу посоветовать вам курс на MVA ( портал совершенно бесплатный )
    www.microsoftvirtualacademy.com/training-courses/developer-training-with-programming-in-c
    Довольно интересная, обучающая не только C#, но и при желании и Java онлайн игра находится по адресу www.codehunt.com В качестве подготавливающей к тестированию она не подойдет, но может быть интересна в качестве разминки.

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

    На этом «вредные» советы заканчиваются. Это лишь только часть того что нужно знать и помнить.
    Желаю всем высоких баллов, а также, конечно же, знаний и понимания языка C#

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 17

      0
      Так вы сдали тест?
      Есть ли смысл в это ввязываться «просто для себя»?
      В том смысле, оправдана ли стоимость? Сколько стоит, кстати?
      И много ли вы узнали нового, получили полезного опыта во время подготовки?
        0
        Стоит, особенно для себя. Порой раскрываются весьма интересные темы, которых не знал раньше. Да и в любом случае это плюс.
        По ссылке можно попробовать бесплатную симуляцию теста exambraindumps.com/70-483.html
        0
        Да, сдал. Подождал акцию «Second Shot» ( это когда по цене одного экзамена можно сделать 2 попытки сдачи ) и спокойно сдал со второй попытки. Время от времени бывают скидки или вот такая акция практиковалась.
        В первый раз не хватило времени.
        После подготовки считаю, что уровень мой поднялся значительно. То есть узнал много нового. Нужен был какой-то стимул для развития и тестирование послужило им. А до этого у меня уже был сертификат в другой области, поэтому этот получал скорее для себя и для самоутверждения.
        Стоимость 60 Евро, но я сдавал в Минске и в сумме ( со всеми налогами и чем-то не знаю еще чем ) получилось больше 80-ти.
          –1
          Спасибо за ответ. Тогда я тоже займусь.
          Дело в том, что я провожу вебинары по C#, записываю видеоуроки, которые выкладываю на своём сайте. Думаю, наличие сертификата будет не только хорошим стимулом к саморазвитию, но и дополнительным аргументом «ценности» моих видеоуроков.
          0
          А сколько у вас опыта с C#? Планирую сдавать экзамены для получения MCSD: Web Applications, в интернетах очень неоднозначная информация по экзамену — кто-то с серьёзным опытом не сдаёт с первого раза, а кто-то считает экзамен достаточно простым.
            0
            У меня больше опыта VB.Net. На C# перешел всего пару лет назад. Довольно непривычно сперва было. До сих пор иногда путаю синтаксис JS/VB и C#. Сейчас не жалею, даже рад переходу.
            Мне когда сдавал первый раз показалось что времени далось очень-очень мало. Часа полтора. Его не хватило ( да и на перевод и осмысливание лишнего вводного текста много времени потратил ). А второй раз я обратил внимание на время. И его было с лихвой.
            Точно не сильно простой. Некоторые вопросы да, простые. А некоторые из разряда «Папа, ты сейчас с кем разговаривал...». На рассмотрение одного такого вопроса понадобится целая статья.
            Для меня неприятным сюрпризом были какие-то вопросы по настройке Visual Studio, либо вопросы организации проекта ( я не работал над крупными проектами ).
            +1
            а что-за проект? не очень понял.
              0
              Проект называется «C# — практические вебинары, видеокурсы и задачи», videosharp.info. Хотя он больше для начинающих, но задач попрактиковаться хватит не на один месяц.
                +1
                Приятный сайт, даже вполне себе портал!
              +1
              Не так давно тоже сдавал этот экзамен. Возможно, кому-нибудь пригодится моя история: Получение MCP: личный опыт.
                0
                А почему не советуете наследоваться от ApplicationException?
                  0
                  На этот вопрос я бы ответил материалом из MSDN, но да, заметил неточность:
                  ApplicationException
                  Смотрите в заметках:
                  «Изначально предполагалось, что пользовательские исключения должны наследовать от класса ApplicationException, однако на практике это не имеет особого значения.»
                  Я полагаю, что это перевод:
                  «For most applications, derive custom exceptions from the Exception class. It was originally thought that custom exceptions should derive from the ApplicationException class; however in practice this has not been found to add significant value.»
                  Я брал информацию из этого источника:
                  JEFFREY RICHTER: System.ApplicationException is a class that should not be part of the .NET Framework. The original idea was that classes derived from SystemException would indicate exceptions thrown from the CLR (or system) itself, whereas non-CLR exceptions would be derived from ApplicationException
                  0
                  Статья полезная, но, как мне показалось, если есть опыт работы с языком хотя бы года два, да хотя бы чуть-чуть почитывали Скита с Рихтером, то к этому экзамену можно не готовиться, не смотреть никаких дампов и сдать с первого раза очень спокойно. По крайней мере у меня прокатило.
                  • UFO just landed and posted this here
                      0
                      так для успешной сдачи экзамена ведь не обязательно ответить верно на все вопросы. там, кажется, то ли 75, то ли 80 процентов достаточно. да и даже в этом случае ответы на многие вопросы, которые не знаешь, можно вывести логически.
                    +2
                    также value тип не может содержать в себе значение null.

                    Nullable-типы относятся к value типам и могут принимать значение null.
                    В принципе, почти весь изложенный материал есть в спецификации и у Рихтера в CLR via C#.
                      –2
                      Информация с MSDN:
                      Nullable types represent value-type variables that can be assigned the value of null. You cannot create a nullable type based on a reference type. (Reference types already support the null value.)
                      The syntax T? is shorthand for System.Nullable, where T is a value type.
                      Другими словами reference типы уже поддерживают значение null, а value типам для поддержки нужно стать частью System.Nullable
                      В статье есть упоминание об int?

                    Only users with full accounts can post comments. Log in, please.