SlideShare ist ein Scribd-Unternehmen logo
1 von 29
Deep Dive
Сергей Тепляков, Visual C# MVP
.NET Architect at Luxoft
SergeyTeplyakov.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 25
for 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); // 1
var s = seq.Select(line => line.Length); // 2
Console.WriteLine(s.Max()); // 3
Все ли нормально с
кодом?
Этот же подход
используется и для
асинхронных методов!
Когда получим
исключение?
Код до первого yield
return вызовется при
первом вызове метода
MoveNext!
Какое исключение получим?
class Foo
{
public Foo() { throw new Exception("Ooops!!"); }
}
static T Create<T>() where T : new()
{
var instance = new T();
// Write to log some message
return 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; // вызываем из потока 1
a.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); // 2
hack.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 on
Programming 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/

Weitere ähnliche Inhalte

Was ist angesagt?

Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о BoostSergey Platonov
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Yauheni Akhotnikau
 
Максим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsМаксим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsPlatonov Sergey
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Sergey Platonov
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Sergey Platonov
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеPython Meetup
 
Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“
Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“
Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“Platonov Sergey
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptSergey Platonov
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковSergey Platonov
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castRoman Orlov
 
Haskell
HaskellHaskell
HaskellDevDay
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3Eugeniy Tyumentcev
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
 
Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Victor_Cr
 
разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2Eugeniy Tyumentcev
 

Was ist angesagt? (20)

Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о Boost
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
Максим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsМаксим Хижинский Lock-free maps
Максим Хижинский Lock-free maps
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгирование
 
Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“
Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“
Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложений
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
 
Zagursky
ZagurskyZagursky
Zagursky
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
Haskell
HaskellHaskell
Haskell
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 
Clojure #2 (2014)
Clojure #2 (2014)Clojure #2 (2014)
Clojure #2 (2014)
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
 
Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)
 
Clojure #1
Clojure #1Clojure #1
Clojure #1
 
Java 8 puzzlers
Java 8 puzzlersJava 8 puzzlers
Java 8 puzzlers
 
разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2
 

Ähnlich wie C# Deep Dive

C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному кодуVasiliy Deynega
 
NetworkUA - 2012 - Introduction TypeScript
NetworkUA - 2012 - Introduction TypeScript NetworkUA - 2012 - Introduction TypeScript
NetworkUA - 2012 - Introduction TypeScript Dmytro Mindra
 
Ciklum .NET Saturday - Introduction to TypeScript
Ciklum .NET Saturday - Introduction to TypeScriptCiklum .NET Saturday - Introduction to TypeScript
Ciklum .NET Saturday - Introduction to TypeScriptDmytro Mindra
 
Statis code analysis
Statis code analysisStatis code analysis
Statis code analysischashnikov
 
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...Sigma Software
 
Язык программирования C#
Язык программирования C#Язык программирования C#
Язык программирования C#Dmitri Soshnikov
 
Scala and LiftWeb presentation (Russian)
Scala and LiftWeb presentation (Russian)Scala and LiftWeb presentation (Russian)
Scala and LiftWeb presentation (Russian)Dmitry Stropalov
 
Convert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at VizorConvert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at VizorDevGAMM Conference
 
Web осень 2012 лекция 9
Web осень 2012 лекция 9Web осень 2012 лекция 9
Web осень 2012 лекция 9Technopark
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокAndrey Karpov
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Stfalcon Meetups
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6Dmitry Soshnikov
 
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...OdessaFrontend
 

Ähnlich wie C# Deep Dive (20)

Асинхронный JavaScript
Асинхронный JavaScriptАсинхронный JavaScript
Асинхронный JavaScript
 
Reactive extensions
Reactive extensionsReactive extensions
Reactive extensions
 
C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному коду
 
NetworkUA - 2012 - Introduction TypeScript
NetworkUA - 2012 - Introduction TypeScript NetworkUA - 2012 - Introduction TypeScript
NetworkUA - 2012 - Introduction TypeScript
 
Ciklum .NET Saturday - Introduction to TypeScript
Ciklum .NET Saturday - Introduction to TypeScriptCiklum .NET Saturday - Introduction to TypeScript
Ciklum .NET Saturday - Introduction to TypeScript
 
Bytecode
BytecodeBytecode
Bytecode
 
Statis code analysis
Statis code analysisStatis code analysis
Statis code analysis
 
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
 
Thread
ThreadThread
Thread
 
JavaScript Intro
JavaScript IntroJavaScript Intro
JavaScript Intro
 
Язык программирования C#
Язык программирования C#Язык программирования C#
Язык программирования C#
 
Scala and LiftWeb presentation (Russian)
Scala and LiftWeb presentation (Russian)Scala and LiftWeb presentation (Russian)
Scala and LiftWeb presentation (Russian)
 
Convert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at VizorConvert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at Vizor
 
Scala on android
Scala on androidScala on android
Scala on android
 
Web осень 2012 лекция 9
Web осень 2012 лекция 9Web осень 2012 лекция 9
Web осень 2012 лекция 9
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибок
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6
 
Scala for android
Scala for androidScala for android
Scala for android
 
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
 

Mehr von LuxoftTraining

Адаптивный дом
Адаптивный домАдаптивный дом
Адаптивный домLuxoftTraining
 
Basic networking course
Basic networking courseBasic networking course
Basic networking courseLuxoftTraining
 
Лучшие практики исполнения проекта в соответствии с методологией IBM Rational
Лучшие практики исполнения проекта в соответствии с методологией IBM RationalЛучшие практики исполнения проекта в соответствии с методологией IBM Rational
Лучшие практики исполнения проекта в соответствии с методологией IBM RationalLuxoftTraining
 
Gobov denys (it arena 2015)
Gobov denys (it arena 2015)Gobov denys (it arena 2015)
Gobov denys (it arena 2015)LuxoftTraining
 
Remigiusz dudek exploratorytests_testwarez2014
Remigiusz dudek exploratorytests_testwarez2014Remigiusz dudek exploratorytests_testwarez2014
Remigiusz dudek exploratorytests_testwarez2014LuxoftTraining
 
От бизнес-систем к информационным системам: переход шаг за шагом
От бизнес-систем к информационным системам: переход шаг за шагомОт бизнес-систем к информационным системам: переход шаг за шагом
От бизнес-систем к информационным системам: переход шаг за шагомLuxoftTraining
 
Kumskov it arena-lviv-2014-10-03
Kumskov it arena-lviv-2014-10-03Kumskov it arena-lviv-2014-10-03
Kumskov it arena-lviv-2014-10-03LuxoftTraining
 
Рекомендации по проведению экспертной оценки Lt
Рекомендации по проведению экспертной оценки LtРекомендации по проведению экспертной оценки Lt
Рекомендации по проведению экспертной оценки LtLuxoftTraining
 
Awinning culture33rddegree
Awinning culture33rddegreeAwinning culture33rddegree
Awinning culture33rddegreeLuxoftTraining
 
Awinning culture33rddegree
Awinning culture33rddegreeAwinning culture33rddegree
Awinning culture33rddegreeLuxoftTraining
 
Waterfall revisited: практические метрики тестирования
Waterfall revisited: практические метрики тестированияWaterfall revisited: практические метрики тестирования
Waterfall revisited: практические метрики тестированияLuxoftTraining
 
Веб-служба на базе Workflow foundation
Веб-служба на базе Workflow foundationВеб-служба на базе Workflow foundation
Веб-служба на базе Workflow foundationLuxoftTraining
 
Soft labs. достижима ли в c++ эффективность языка среднего уровня
Soft labs. достижима ли в c++ эффективность языка среднего уровняSoft labs. достижима ли в c++ эффективность языка среднего уровня
Soft labs. достижима ли в c++ эффективность языка среднего уровняLuxoftTraining
 
Презентация доклада Лавриненко
Презентация доклада ЛавриненкоПрезентация доклада Лавриненко
Презентация доклада ЛавриненкоLuxoftTraining
 
Secr презентация дружинина
Secr презентация дружининаSecr презентация дружинина
Secr презентация дружининаLuxoftTraining
 
Secr презентация гардиенков
Secr презентация гардиенковSecr презентация гардиенков
Secr презентация гардиенковLuxoftTraining
 
Опыт Объектно Ориентированного подхода в Бизнес-Анализе
Опыт Объектно Ориентированного подхода в Бизнес-АнализеОпыт Объектно Ориентированного подхода в Бизнес-Анализе
Опыт Объектно Ориентированного подхода в Бизнес-АнализеLuxoftTraining
 
Концепция построения процесса тестирования в Agile проектах: 3+1
Концепция построения процесса тестирования в Agile проектах: 3+1Концепция построения процесса тестирования в Agile проектах: 3+1
Концепция построения процесса тестирования в Agile проектах: 3+1LuxoftTraining
 

Mehr von LuxoftTraining (20)

Адаптивный дом
Адаптивный домАдаптивный дом
Адаптивный дом
 
Basic networking course
Basic networking courseBasic networking course
Basic networking course
 
Take a sip of sip
Take a sip of sipTake a sip of sip
Take a sip of sip
 
Лучшие практики исполнения проекта в соответствии с методологией IBM Rational
Лучшие практики исполнения проекта в соответствии с методологией IBM RationalЛучшие практики исполнения проекта в соответствии с методологией IBM Rational
Лучшие практики исполнения проекта в соответствии с методологией IBM Rational
 
Gobov denys (it arena 2015)
Gobov denys (it arena 2015)Gobov denys (it arena 2015)
Gobov denys (it arena 2015)
 
Remigiusz dudek exploratorytests_testwarez2014
Remigiusz dudek exploratorytests_testwarez2014Remigiusz dudek exploratorytests_testwarez2014
Remigiusz dudek exploratorytests_testwarez2014
 
От бизнес-систем к информационным системам: переход шаг за шагом
От бизнес-систем к информационным системам: переход шаг за шагомОт бизнес-систем к информационным системам: переход шаг за шагом
От бизнес-систем к информационным системам: переход шаг за шагом
 
Kumskov it arena-lviv-2014-10-03
Kumskov it arena-lviv-2014-10-03Kumskov it arena-lviv-2014-10-03
Kumskov it arena-lviv-2014-10-03
 
Рекомендации по проведению экспертной оценки Lt
Рекомендации по проведению экспертной оценки LtРекомендации по проведению экспертной оценки Lt
Рекомендации по проведению экспертной оценки Lt
 
Awinning culture33rddegree
Awinning culture33rddegreeAwinning culture33rddegree
Awinning culture33rddegree
 
Awinning culture33rddegree
Awinning culture33rddegreeAwinning culture33rddegree
Awinning culture33rddegree
 
Waterfall revisited: практические метрики тестирования
Waterfall revisited: практические метрики тестированияWaterfall revisited: практические метрики тестирования
Waterfall revisited: практические метрики тестирования
 
Веб-служба на базе Workflow foundation
Веб-служба на базе Workflow foundationВеб-служба на базе Workflow foundation
Веб-служба на базе Workflow foundation
 
Soft labs. достижима ли в c++ эффективность языка среднего уровня
Soft labs. достижима ли в c++ эффективность языка среднего уровняSoft labs. достижима ли в c++ эффективность языка среднего уровня
Soft labs. достижима ли в c++ эффективность языка среднего уровня
 
Vs vs. charles
Vs vs. charlesVs vs. charles
Vs vs. charles
 
Презентация доклада Лавриненко
Презентация доклада ЛавриненкоПрезентация доклада Лавриненко
Презентация доклада Лавриненко
 
Secr презентация дружинина
Secr презентация дружининаSecr презентация дружинина
Secr презентация дружинина
 
Secr презентация гардиенков
Secr презентация гардиенковSecr презентация гардиенков
Secr презентация гардиенков
 
Опыт Объектно Ориентированного подхода в Бизнес-Анализе
Опыт Объектно Ориентированного подхода в Бизнес-АнализеОпыт Объектно Ориентированного подхода в Бизнес-Анализе
Опыт Объектно Ориентированного подхода в Бизнес-Анализе
 
Концепция построения процесса тестирования в Agile проектах: 3+1
Концепция построения процесса тестирования в Agile проектах: 3+1Концепция построения процесса тестирования в Agile проектах: 3+1
Концепция построения процесса тестирования в Agile проектах: 3+1
 

C# Deep Dive

  • 1. Deep Dive Сергей Тепляков, Visual C# MVP .NET Architect at Luxoft SergeyTeplyakov.blogspot.com
  • 2. А насколько глубоко будем нырять?
  • 3. Настолько глубоко? 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!!!!
  • 4. Нет! Нет! Нет! • Подробнее об этом треше - http://rsdn.ru/forum/dotnet/3272728.flat • См. этюды nikov-а на rsdn.ru – http://rsdn.ru/Forum/?fuid=55905 • Кури “The C# Programming Language” by Hejlsberg et al!
  • 5. Что нужно для работы цикла foreach? • IEnumerable? • IEnumerable of T? • Что-то еще? • Нужен метод GetEnumerator, возвращающий объект с методом MoveNext и свойством Current!
  • 6. В F# пошли еще дальше… • Поддержку цикла for можно добавить с помощью методов расширения! type Int32 with // Получаем список квадратов чисел от 1 до текущего значения member x.GetEnumerator() = ({1..x} |> Seq.map(fun x -> x*x)).GetEnumerator() // Выводит 1 4 9 16 25 for n in 5 do printf "%d " n
  • 7. Утиная типизация Если кто-то ходит, как утка, и крякает, как утка, то это и есть может быть утка индюшка с утиным адаптером...
  • 8. «Утиная типизация» в 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 • Методы расширения завязаны не на конкретный тип атрибутов!
  • 9. Блоки итераторов… 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); // 1 var s = seq.Select(line => line.Length); // 2 Console.WriteLine(s.Max()); // 3 Все ли нормально с кодом? Этот же подход используется и для асинхронных методов! Когда получим исключение? Код до первого yield return вызовется при первом вызове метода MoveNext!
  • 10. Какое исключение получим? class Foo { public Foo() { throw new Exception("Ooops!!"); } } static T Create<T>() where T : new() { var instance = new T(); // Write to log some message return instance; } var f = Create<Foo>(); Какое исключение получим?
  • 11. Почему? • Используется reflection (Activator.CreateInstance). • Все обобщения должны содержать одну реализацию! • Вызов метода через Reflection всегда «оборачивает» исходное исключение в TargetInvocationException • «Все нетривиальные абстракции текут» Джоэл Спольски
  • 12. Есть ли проблема? using (var file = new FileStream("D:1.txt", FileMode.CreateNew) { Position = RestoreLastPosition() }) {}
  • 13. Как устроен 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;
  • 14. Как устроен 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(); }
  • 15. Складываем 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(); }
  • 16. Потокобезопасная подписка на событие? 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; // вызываем из потока 1 a.Subscribe(handler); // вызываем из потока 2 Подробнее об этом – Chris Burrow "Events get a little overhaul in C# 4, Part II" Является ли такая подписка «изнутри» потокобезопасной? Такой вариант не безопасен!
  • 17. Как устроены события? 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!
  • 18. В 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); } }
  • 19. Делегаты… static void SubscribeTo(EventHandler e) { e += (s, ea) => Console.WriteLine("Custom handler"); } EventHandler handler = null; SubscribeTo(handler); handler(null, EventArgs.Empty); Что произойдет при вызове?
  • 20. Делегаты – неизменяемы… • Ведь этот трюк все же знают! class A { public event EventHandler E; public void RaiseE() { var handler = E; if (handler != null) handler(this, EventArgs.Empty); } } Не на 100% thread-safe в теории, но thread-safe на практике!
  • 21. Виртуальные события 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();
  • 22. 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!!
  • 23. 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); // 2 hack.Hacker.Length = 42; Console.WriteLine(hack.Array.Length); // 42!! hack.Array.Dump(); // Получаем "мусор" } Изменяем размер массива! Первые 4 байта массива – это его размер!
  • 24. А стоит ли их вообще использовать? • А как же! Ногу, ведь, чем-то нужно отпиливать! • Есть приложения, а есть библиотеки – это разные миры. • Понимание внутреннего устройства сведет проблемы к минимуму!
  • 27. Чего еще почитать? • Programming Stuff • C# Tips and Tricks • Chris Burrows’ Blog • Eric Lippert’s Blog • Joe Duffy’s Weblog • B# .NET BLOG
  • 28. More C# Deep Dive on Programming Stuff • this == null? • Замыкания в языке C# • Перегрузка и наследование • Структуры и конструкторы по умолчанию • О вреде изменяемых значимых типов. • Часть 1 • Часть 2 • MVP Summit. День 0. Кэширование делегатов • MVP Summit. День 1. Об эффективности
  • 29. Спасибо за внимание • Сергей Тепляков, Visual C# MVP • .NET Architect at Luxoft • Sergey.Teplyakov@gmail.com • http://sergeyteplyakov.blogspot.com/

Hinweis der Redaktion

  1. Тут приходит в голову очень пошлая фотка)
  2. // TODO: Сделать пометки, почему ведет себя код именно так! Сказать, что readonly – доступ к ней – это не обращение к переменной, а получение значения! Добавить b.M.Y++, что это тоже не компилится, поскольку b.M - rvalue