Гайдар Магдануров Microsoft
static void Main(string[] args) { Console.WriteLine(GetSomeResult(10000)); } static long GetSomeResult(long someValue) { long value1 = 10 * 1000 * * someValue; long value2 = 10 * 1000 * * ; return value2 / value1; } За длинным числом погонишься… Не компилируется. Переполнение.
static void Main(string[] args) { Console.WriteLine(GetSomeResult(10000)); } static long GetSomeResult(long someValue) { long value1 = 10 * 1000 * * someValue; long value2 = 10 * 1000 * * L; return value2 / value1; } За длинным числом погонишься…
Я – не я? float x; Console.Write(x == x) Как это может быть? Выводит False. // Особенности float NaN float x = float.NaN;
Он или не он, вот в чем вопрос… public static void Main() { Test t = new Test(); Console.WriteLine(t.Equals(t)); } Метод Equals, наследуемый от Object, сравнивает ссылки. А тут, что за дела? Выводит False. public class Test { public bool Equals(Test t) { return false; } }
static void Main(string[] args) { char a = 'a'; int b = 0; Console.WriteLine(true ? a : b); } 97 Типы операндов не совпадают и компилятор приводит оба типа к общему совместимому Int32. Тернарный условный оператор
Условный оператор в интересных условиях NameValueCollection col = new NameValueCollection(); Console.WriteLine( "Элемент test " + col["test"] != null ? "Существует!" : "Не существует!"); Существует! Сначала работает оператор +, после этого сравнивается с null строка «Это test».
Конкатенируя конкатенируй Console.WriteLine("A" + "B" + "C"); Console.WriteLine('A' + 'B' + 'C'); ABC 198 Оператор «+» не определен для char, поэтому выполняется приведение к Int32.
Циклическая инициализация public class A { public static int x = B.y + 1; } public class B { public static int y = A.x + 1; } static void Main(string[] args) { Console.WriteLine("A.x = " + A.x); Console.WriteLine("B.y = " + B.y); } Вызывается конструктор A, затем конструктор B, но т.к. не определено значение A.x, то для используется 0 в конструкторе B. A.x = 2 B.y = 1
Инкремент инкременту волк int j = 0; for (int i = 0; i < 10; i++) j = j++; Console.WriteLine(j); Оператор ++ возвращает значение до инкрементации, поэтому j сохраняет исходное значение. 0
На пределе возможностей int end = int.MaxValue; int begin = end - 100; int counter = 0; for (int i = begin; i
Большие числа, большие проблемы float begin = ; int counter = 0; for (float i = begin; i < (begin + 10); i++) counter++; Console.WriteLine(counter); Для таких больших значений float нет разницы между begin и begin + 10, но компилятор что-то подозревает. Использовать int/long счетчик цикла. Бесконечный цикл
Кто компилятору милее class A { public void Test(int n) { Console.WriteLine("A"); } } class B : A { public void Test(double n) { Console.WriteLine("B"); } } static void Main(string[] args) { B b = new B(); b.Test(5); } Приоритет отдается методу класса, по типу ссылки, если в нем определен метод с типами аргументов позволяющих выполнить преобразование без потерь. B
Кто компилятору милее class A { public void Test(double n) { Console.WriteLine("A"); } } class B : A { public void Test(int n) { Console.WriteLine("B"); } } static void Main(string[] args) { B b = new B(); b.Test(5.0); }
Кто компилятору милее 2 public class Test { public Test(object obj) { Console.WriteLine("object"); } public Test(int[] obj) { Console.WriteLine("int[]"); } public Test(float[] obj) { Console.WriteLine("float[]"); } } public static void Main() { Test t = new Test(null); } Не компилируется. Неоднозначность конструкторов.
Кто компилятору милее 3 public class Test { public Test(object obj) { Console.WriteLine("object"); } public Test(int[] obj) { Console.WriteLine("int[]"); } } public static void Main() { Test t = new Test(null); } Int[] Компилятор при определении вызова не использует текущее значение, а выбирает наиболее «специфический» конструктор. Стоит явно указать тип: new Test((object)null);
Анонимные типы в C# Синтаксис: var anonType = new { FirstName = "John", LastName = "Lennon" }; Компилятор создает некий базымянный тип, область видимости которого ограничена текущей областью видимости в которой объявлен анонимный тип.
Общие типы (Generics) в C# Синтаксис: public class Stack { private T[] items; public void Push(T item) { } public T Pop() { } } Возможность использования одного класса для работы с разными типами a la шаблоны C++.
Свободу попугаям! Возможно ли использовать общую (generic) коллекцию для анонимных типов? Например, List ? Можно ли передать объект анонимного типа в другую область видимости?
Докатились List … var beatlesMember = new { FirstName = "John", LastName = "Lennon" }; var beatlesList = (new[] { beatlesMember }).ToList(); beatlesList.Add(new { FirstName = "Paul", LastName = "McCartney" }); Пример использования типа «по образцу».
Передача анонимного типа в другую область видимости? Час от часу … static object GetBeatleName() { return new { First = John", Last = Lennon" }; } static T CastType (object obj, T type) { return (T)obj; } static void Main() { object o = GetBeatleName(); var typed = CastType(o, new { First = "", Last = "" }); Console.WriteLine(First={0}, Last={1}", typed.First, typed.Last); } Пример использования типа «по образцу». First=John Last=Lennon
Лямбда-выражения в C# Синтаксис для записи анонимного делегата: item => item < 3 равнозначно delegate(int item) { return item < 3; } Пример использования: List list = new List () { 1, 2, 3, 4, 5 }; var q = list.FindAll(item => item < 3);
Танец с лямбдами delegate bool TestDelagate(); static void Test(TestDelagate del) { Console.WriteLine(del()); } static void Main() { Test(p => true); } Делегат, не принимающий параметров, описывается () => true. Не компилируется
Простая считалочка List list = new List () { 1, 2, 3, 4, 5 }; List all = list.FindAll( i => { Console.Write(i); return i < 3; } ); Делегат, переданный методу FindAll вызывается для каждого элемента
Считалочка посложнее List list = new List () { 1, 2, 3 }; var x = list.GroupBy(i => { Console.Write(i); return i; }); var y = list.ToLookup(i => { Console.Write(i); return i; }); Выполнение GroupBy отложено до обращения к результату. Вывод будет если дописать, например, строку var z = x.ToArray(); 123
И, наконец … try { Console.WriteLine("Hello "); return; } finally { Console.WriteLine("Goodbye "); } Console.WriteLine("world!"); Finally выполняется даже если выполнение прервано по return. Hello Goodbye
И еще, наконец… try { Console.WriteLine("Hello "); Thread.CurrentThread.Abort(); } finally { Console.WriteLine("Goodbye "); } Console.WriteLine("world!"); Abort выбрасывает исключение ThreadAbortException, которое обрабатывается finally, затем выполнение прерывается. Hello Goodbye
Все, совсем все! try { Console.WriteLine("Hello "); System.Environment.Exit(0); } finally { Console.WriteLine("Goodbye "); } Console.WriteLine("world!"); Выполнение программы прерывается в точке вызова System.Environment.Exit(0); Hello
Гайдар Магдануров Microsoft СПАСИБО ЗА ВНИМАНИЕ!
BLOGS.MSDN.COM/GAIDAR