подводные камни Csharp.pptx
- Количество слайдов: 27
<Подводные камни C#> Гайдар Магдануров Microsoft
http: //www. microsoft. com/express/ru/
За длинным числом погонишься… static void Main(string[] args) { Console. Write. Line(Get. Some. Result(10000)); } static long Get. Some. Result(long some. Value) { long value 1 = 10 * 10000 * some. Value; long value 2 = 10 * 100000; return value 2 / value 1; } Не компилируется. Переполнение.
За длинным числом погонишься… static void Main(string[] args) { Console. Write. Line(Get. Some. Result(10000)); } static long Get. Some. Result(long some. Value) { long value 1 = 10 * 10000 * some. Value; long value 2 = 10 * 100000 L; return value 2 / value 1; }
Я – не я? float x = float. Na. N; Console. Write(x == x) Как это может быть? Выводит False.
Он или не он, вот в чем вопрос… public static void Main() { Test t = new Test(); Console. Write. Line(t. Equals(t)); } Выводит False. Метод Equals, наследуемый от Object, сравнивает ссылки. А тут, что за дела? public class Test { public bool Equals(Test t) { return false; } }
Тернарный условный оператор static void Main(string[] args) { char a = 'a'; int b = 0; Console. Write. Line(true ? a : b); } 97 Типы операндов не совпадают и компилятор приводит оба типа к общему совместимому Int 32.
Конкатенируя конкатенируй Console. Write. Line("A" + "B" + "C"); Console. Write. Line('A' + 'B' + 'C'); ABC 198 Оператор «+» не определен для char, поэтому выполняется приведение к Int 32.
Циклическая инициализация 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. Write. Line("A. x = " + A. x); Console. Write. Line("B. y = " + B. y); } A. x = 2 B. y = 1 Вызывается конструктор A, затем конструктор B, но т. к. не определено значение A. x, то для x используется 0 в конструкторе B.
Инкремент инкременту волк int j = 0; for (int i = 0; i < 10; i++) j = j++; 0 Console. Write. Line(j); Оператор ++ возвращает значение до инкрементации, поэтому j сохраняет исходное значение.
На пределе возможностей int end = int. Max. Value; int begin = end - 100; int counter = 0; for (int i = begin; i <= end; i++) { counter++; Console. Write. Line(counter); } Бесконечный цикл Все переменные типа Int 32 меньше или равны Int 32. Max. Value.
Большие числа, большие проблемы float begin = 100000; int counter = 0; for (float i = begin; i < (begin + 10); i++) counter++; Бесконечный цикл Console. Write. Line(counter); Для таких больших значений float нет разницы между begin и begin + 10, но компилятор что-то подозревает. Использовать int/long счетчик цикла.
Кто компилятору милее class A { public void Test(int n) { Console. Write. Line("A"); } } class B : A { public void Test(double n) { Console. Write. Line("B"); } } static void Main(string[] args) { B b = new B(); b. Test(5); } B Приоритет отдается методу класса, по типу ссылки, если в нем определен метод с типами аргументов позволяющих выполнить преобразование без потерь.
Кто компилятору милее class A { public void Test(double n) { Console. Write. Line("A"); } } class B : A { public void Test(int n) { Console. Write. Line("B"); } } static void Main(string[] args) { B b = new B(); b. Test(5. 0); }
Кто компилятору милее 2 public class Test { public Test(object obj) { Console. Write. Line("object"); } public Test(int[] obj) { Console. Write. Line("int[]"); } public Test(float[] obj) { Console. Write. Line("float[]"); } } public static void Main() { Test t = new Test(null); } Не компилируется. Неоднозначность конструкторов.
Кто компилятору милее 3 public class Test { public Test(object obj) { Console. Write. Line("object"); } public Test(int[] obj) { Console. Write. Line("int[]"); } } Int[] public static void Main() { Test t = new Test(null); } Компилятор при определении вызова не использует текущее значение, а выбирает наиболее «специфический» конструктор. Стоит явно указать тип: new Test((object)null);
И, наконец … try { Hello Goodbye Console. Write. Line("Hello "); return; } finally { Console. Write. Line("Goodbye "); } Console. Write. Line("world!"); Finally выполняется даже если выполнение прервано по return.
И еще, наконец… try { Hello Goodbye Console. Write. Line("Hello "); Thread. Current. Thread. Abort(); } finally { Console. Write. Line("Goodbye "); } Console. Write. Line("world!"); Abort выбрасывает исключение Thread. Abort. Exception, которое обрабатывается finally, затем выполнение прерывается.
Все, совсем все! try { Console. Write. Line("Hello "); System. Environment. Exit(0); } finally { Console. Write. Line("Goodbye "); } Hello Console. Write. Line("world!"); Выполнение программы прерывается в точке вызова System. Environment. Exit(0);
СПАСИБО ЗА ВНИМАНИЕ! Подводные камни C#> Гайдар Магдануров Microsoft
GAIDARMA@MICROSOFT. COM BLOGS. MSDN. COM/GAIDAR