• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
C sharp deep dive
 

C sharp deep dive

on

  • 891 views

 

Statistics

Views

Total Views
891
Views on SlideShare
838
Embed Views
53

Actions

Likes
4
Downloads
0
Comments
0

2 Embeds 53

https://twitter.com 33
http://hotcode.org 20

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Тут приходит в голову очень пошлая фотка)
  • // TODO: Сделать пометки, почему ведет себя код именно так! Сказать, что readonly – доступ к ней – это не обращение к переменной, а получение значения! Добавить b.M.Y++, что это тоже не компилится, поскольку b.M - rvalue

C sharp deep dive C sharp deep dive Presentation Transcript

  • Deep DiveСергей Тепляков, Visual C# MVP.NET Architect at LuxoftSergeyTeplyakov.blogspot.com
  • А насколько глубоко будемнырять?
  • Настолько глубоко?class X { public const int Value = 1000; }static int Foo(Func<int?, byte> x, object y) { return 1; }static int Foo(Func<X, byte> x, string y) { return 2; }var a = Foo(X => (byte)X.Value, null);unchecked{Console.WriteLine(a);}unchecked{var a = Foo(X => (byte)X.Value, null);Console.WriteLine(a);}unchecked{var a = Foo(X => (byte)X.Value, (object)null);Console.WriteLine(a);} Увидим 1Увидим 2Снова 1!!!!
  • Нет! Нет! Нет!• Подробнее об этом треше -http://rsdn.ru/forum/dotnet/3272728.flat• См. этюды nikov-а на rsdn.ru –http://rsdn.ru/Forum/?fuid=55905• Кури “The C# Programming Language” by Hejlsberg et al!
  • Что нужно для работы циклаforeach?• IEnumerable?• IEnumerable of T?• Что-то еще?• Нужен метод GetEnumerator, возвращающийобъект с методом MoveNext и свойствомCurrent!
  • В F# пошли еще дальше…• Поддержку цикла for можно добавить с помощью методоврасширения!type Int32 with// Получаем список квадратов чисел от 1 до текущего значенияmember x.GetEnumerator() =({1..x} |> Seq.map(fun x -> x*x)).GetEnumerator()// Выводит 1 4 9 16 25for n in 5 do printf "%d " n
  • Утиная типизацияЕсли кто-то ходит, как утка, и крякает, какутка, то это и есть может быть утка индюшкас утиным адаптером...
  • «Утиная типизация» в C#• foreach• Требуется GetEnumerator, MoveNext и свойство Current• http://sergeyteplyakov.blogspot.com/2012/08/duck-typing-foreach.html• LINQ (Query Comprehension syntax)• Требуются методы Select, Where, GroupBy etc.• Collection initializer• Требуется метод Add• C# 5.0 Async Features• Требуются GetAwaiter() и методы BeginAwait(Action) иEndAwait(), GetResult() и свойства IsCompleted.• System.Runtime.CompilerServices.ExtensionAttribute• Методы расширения завязаны не на конкретный типатрибутов!
  • Блоки итераторов…public static IEnumerable<string> ReadByLine(string path){if (string.IsNullOrEmpty(path))throw new ArgumentNullException("path");using (var sr = new StreamReader(path)){string s;while ((s = sr.ReadLine()) != null)yield return s;}}var seq = ReadByLine(null); // 1var s = seq.Select(line => line.Length); // 2Console.WriteLine(s.Max()); // 3Все ли нормально скодом?Этот же подходиспользуется и дляасинхронных методов!Когда получимисключение?Код до первого yieldreturn вызовется припервом вызове методаMoveNext!
  • Какое исключение получим?class Foo{public Foo() { throw new Exception("Ooops!!"); }}static T Create<T>() where T : new(){var instance = new T();// Write to log some messagereturn instance;}var f = Create<Foo>();Какое исключениеполучим?
  • Почему?• Используется reflection (Activator.CreateInstance).• Все обобщения должны содержать одну реализацию!• Вызов метода через Reflection всегда «оборачивает»исходное исключение в TargetInvocationException• «Все нетривиальные абстракции текут»Джоэл Спольски
  • Есть ли проблема?using (var file = new FileStream("D:1.txt", FileMode.CreateNew){Position = RestoreLastPosition()}){}
  • Как устроен Object Initializer?class Person{public string Name { get; set; }public int Age { get; set; }}// ...var person = new Person {Name = "Jonh", Age = 42};var tmp = new Person();tmp.Name = "Jonh";tmp.Age = 42;var person = tmp;
  • Как устроен using?using (var file = new FileStream("D:1.txt", FileMode.CreateNew)){}var file = new FileStream("d:1.txt", FileMode.CreateNew);try{}finally{if (file != null)((IDisposable)file).Dispose();}
  • Складываем 2 и 2…var tmpFile = new FileStream("d:1.txt", FileMode.CreateNew);// Упс! Если мы здесь упадем, то Dispose вызван не будет!tmpFile.Position = RestoreLastPosition();var file = tmpFile;try{ }finally{if (file != null)((IDisposable)file).Dispose();}
  • Потокобезопасная подпискана событие?class A{public event EventHandler E;public void Subscribe(EventHandler e){E = E + e;}}var a = new A();EventHandler handler = (o, e) => Console.WriteLine("Handler");a.E += handler; // вызываем из потока 1a.Subscribe(handler); // вызываем из потока 2Подробнее об этом –Chris Burrow "Events get a little overhaul in C# 4, Part II"Является ли такаяподписка «изнутри»потокобезопасной?Такой вариант небезопасен!
  • Как устроены события?class AImpl{private EventHandler __E;public event EventHandler E{add{lock (this) { __E += value; }}remove{lock (this) { __E += value; }}}public void Subscribe(EventHandler e){__E = (EventHandler)Delegate.Combine(__E, e);}}В C# 4.0 используетсяlock-free подход.А вместо «сырого»Combine для E+= valueвызываетсяэкземплярный Add!
  • В C# 4.0…• События C# 4.0 полностью потокобезопасны• Подписка на событие «изнутри» класса приводит к вызовуAdd текущего объекта// В C# 4.0 решение полностью потокобезопасно!class A{public event EventHandler E;public void Subscribe(EventHandler e){E += e;}public void RaiseE(){var handler = E;if (handler != null)handler(this, EventArgs.Empty);}}
  • Делегаты…static void SubscribeTo(EventHandler e){e += (s, ea) => Console.WriteLine("Custom handler");}EventHandler handler = null;SubscribeTo(handler);handler(null, EventArgs.Empty);Что произойдет привызове?
  • Делегаты – неизменяемы…• Ведь этот трюк все же знают!class A{public event EventHandler E;public void RaiseE(){var handler = E;if (handler != null)handler(this, EventArgs.Empty);}}Не на 100% thread-safe втеории, но thread-safe напрактике!
  • Виртуальные событияclass Base{public virtual event EventHandler SomeEvent;public void RaiseSomeEvent(){var handler = SomeEvent;if (handler != null)handler(this, EventArgs.Empty);}}class Derived : Base{public override event EventHandler SomeEvent;}Base b = new Derived();b.SomeEvent += (s, e) =>Console.WriteLine("Handler");b.RaiseSomeEvent();
  • struct S1{private readonly int X;public int GetX() { return X; }}struct S2{public int X;}[StructLayout(LayoutKind.Explicit)]struct S3{[FieldOffset(0)]public S1 S1;[FieldOffset(0)]public S2 S2;}var s3 = new S3();s3.S2.X = 42;Console.WriteLine(s3.S1.GetX());Readonly. Правда?X изменить нельзя!Правда ведь?Да это же union из С/С++!!!Получим 42!!
  • class ArrayHacker{public int Length;}[StructLayout(LayoutKind.Explicit)]class ArrayHack{[FieldOffset(0)]public ArrayHacker Hacker;[FieldOffset(0)]public int[] Array = new int[2];}void Main(){var hack = new ArrayHack();Console.WriteLine(hack.Array.Length); // 2hack.Hacker.Length = 42;Console.WriteLine(hack.Array.Length); // 42!!hack.Array.Dump(); // Получаем "мусор"}Изменяем размер массива!Первые 4 байта массива – этоего размер!
  • А стоит ли их вообщеиспользовать?• А как же! Ногу, ведь, чем-то нужно отпиливать!• Есть приложения, а есть библиотеки – это разные миры.• Понимание внутреннего устройства сведет проблемы кминимуму!
  • Нееееттт!!!!1111
  • Вопросы?
  • Чего еще почитать?• Programming Stuff• C# Tips and Tricks• Chris Burrows’ Blog• Eric Lippert’s Blog• Joe Duffy’s Weblog• B# .NET BLOG
  • More C# Deep Dive onProgramming Stuff• this == null?• Замыкания в языке C#• Перегрузка и наследование• Структуры и конструкторы по умолчанию• О вреде изменяемых значимых типов.• Часть 1• Часть 2• MVP Summit. День 0. Кэширование делегатов• MVP Summit. День 1. Об эффективности
  • Спасибо за внимание• Сергей Тепляков, Visual C# MVP• .NET Architect at Luxoft• Sergey.Teplyakov@gmail.com• http://sergeyteplyakov.blogspot.com/