Giter Club home page Giter Club logo

dotnetbook's Introduction

This book is available in:

  • English: If you want to show that you like this book or to express your gratitude to author, Star this project, Fork it and Pull Requests to it.
  • Русском: Если вы хотите показать, что книга вам нравится или выразить благодарность, ставьте звезду проекту, делайте fork и создавайте Pull Requests!
  • 中文: 如果你想表明你喜欢这本书或者表达你对作者的感激之情,请Star、Fork、PR一条龙。

Многим из вас есть, что сказать, чем дополнить главы этого труда. Не стесняйтесь: я помогу и редактурой и переводом на конечные языки.

Cover From Author, Stanislav Sidristij
CLR Book

Introduction

This book was thought as a full description of how .NET CLR and to some extent .NET Framework function. I tried to draw reader's attention to their internals from a different, unusual point of view. Primarily, it is caused by statement — quite disputable — that any software developer must know C/C++. Why? The reason is that among all high-level languages these are the nearest to the CPU, and if you build your program in these languages you feel better how it runs. However, our world looks different than we expect and we often have no time to learn things we won't use; that's why I decided to write this book where issues are explained deeper than usual and with a more intricate or alternative examples. Beyond their standard goal — to show a specific functionality with a simple code — these examples pave the way to alternative reality by showing that things may turn out to be more complicated than they seem. With that in mind, you will feel how every single cog works in CLR.
CLR Book

Введение

Эта книга задумана мной как максимально полное описание работы .NET CLR, и частично - .NET Framework и призвана в первую очередь заставить посмотреть читателя на его внутреннюю структуру под несколько другим углом: не так, как это делается обычно. Связано это в первую очередь с утверждением, которое может показаться многим очень спорным: любой разработчик обязан пройти школу C/C++. Почему? Да потому что из высокоуровневых эти языки наиболее близки к процессору, и программируя на них начинаешь чувствовать работу программы сильнее. Однако, понимая, что мир устроен несколько иначе и у нас зачастую нет никакого времени изучать то, чем мы не будем напрямую пользоваться, я и решил написать эту книгу, в которой объяснение всех вопросов идет с более глубокой чем обычно - позиции и с более сложными или же попросту альтернативными примерами. Которые, помимо своей стандартной миссии - на самом простом коде показать как работает тот или иной функционал, сделать реверанс в альтернативную реальность, показав что все сильно сложнее чем может показаться изначально. Зачем? Чтобы и у вас возникло чувство понимания работы CLR до последнего винтика
CLR Book

介绍

可以说,本书是对.NET CLR原理的全面描述,一定程度上包含了.NET Framework,主旨是为了让读者从一个不同且不寻常的角度来看待它的内部结构。基本上,本书的写作动机来自于一句颇有争议的声明:任何开发人员都必须了解C/C++。为什么呢?原因是在所有高级语言中,这些语言最接近处理器,使用它们编程的时候你更清楚知道它们的工作原理。然而这个世界终究不尽如人意,我们通常并没有时间来研究我们不会直接使用的东西;所以我决定写这本书,鞭辟入里地去分析一些案例,甚至不惜采用更加复杂的或另类的例子。这些例子,除了它们的标准使命,即使用最简单的代码展示某一具体功能外,还通过展示一些事物的发展可能会比想象中更加复杂,借此反映另一种现实。铭记这些,你就会对CLR的每一个组件是如何运作的了然于胸。








wwwwwwwwwwwwwwwwwwwwwwwwwww

dotnetbook's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dotnetbook's Issues

[Disposable] Уточнить термин

Lingvo для Disposable подсказывает среди прочего вариант: выбрасываемый (после употребления). В русскоязычном IT сленге, наверное, «освобожденный» тут мало подходит. Выброшенный, использованный — не говорят и любого закидают тухлыми яйцами если так кто-то скажет :) Тут скорее уже стоит подбирать по смыслу. Кстати если переводить Dispose() как «прекратить использовать», то невыброс AlreadyDisposedException() — правильно и ставит все на свои места. Но перевод не привычен для нашего языка и «разрушение», как мне кажется, меньшее из зол.

[ObjectsStructure] "... и никак не связано с рефлексией"

связанные союзом "И" части этого предложения не сочетаются, а выделение выглядит небоснованным:

В этой структуре нет никакой информации об обычных методах, полях, свойствах (которые объединяют методы) и никак не связано с рефлексией.

HTH

ThreadAbortException может прилететь после вызова CreateFile — но еще до установки значения

mayorovp
07.11.17 в 19:35

Кажется, вы забыли упомянуть о еще одном важном достоинстве SafeHandle. Дело в том, что какой-нибудь ThreadAbortException может прилететь после вызова CreateFile — но еще до установки значения поля _handle. Без использования SafeHandle это приведет к редкой но очень неприятной утечке ресурса.

[Disposable] закрытие хэндлов при (нештатном) завершении процесса

Вы пишете: "...либо заблокируете на долгое время файл на файловой шаре, если он был открыт через средства ОС, но не был закрыт. Пример с файловыми шарами особенно хорош, потому что блокировка останется даже после закрытия приложения: открытость файла регулирует та сторона, на которой он находится. А удаленная сторона не получит сигнала закрытия файла, если вы его не закрыли самостоятельно.".

Однако известно, что в Windows при завершении процесса, штатном или нештатном, все незакрытые хэндлы закрываются. Отвечает за это сама операционная система. Работает это через таблицу хэндлов, которая ассоциирована с процессом. Вот что про это пишет Рихтер (http://wm-help.net/books-online/book/59464/59464-22.html): "А вдруг Вы забыли вызвать CloseHandle — будет ли утечка памяти? И да, и нет. Утечка ресурсов (тех же объектов ядра) вполне вероятна, пока процесс еще исполняется. Однако по завершении процесса операционная система гарантированно освобождает все ресурсы, принадлежавшие этому процессу, и в случае объектов ядра действует так: в момент завершения процесса просматривает его таблицу описателей и закрывает любые открытые описатели.". Поскольку в основе .NET процесса все равно лежит нативный процесс, я не вижу причин, почему в .NET должно быть отличное поведение хэндлов.

Определить лицензию

Добрый день. Я бы хотел немного поконтрибьютить в этот проект, но на данный момент меня останавливает отсутствие лицензии. Мне хотелось бы, чтобы мои изменения обладали внятным легальным статусом.

Можете, пожалуйста, определить лицензию на текст?

Дополнительный пример про explicit реализацию интерфейсов

В секции Раздел вопросов приведен пример реализации IDisposable интерфейса с последующим примечанием про explicit реализацию и каст.

Предлагаю дополнить этот раздел следующим примером, который, ИМХО, дополняет информацией о expilict реализации и о наследовании интерфейсов:
(Пример на VB, так как в C# нет возможности явно переопределить explicit реализацию )

    Class Foo
        Implements IDisposable

        Public Overridable Sub DisposeImp() Implements IDisposable.Dispose
            Console.WriteLine("Foo.IDisposable::Dispose")
        End Sub

        Public Sub Dispose()
            Console.WriteLine("Foo::Dispose()")
        End Sub

    End Class

    Class Boo
        Inherits Foo
        Implements IDisposable

        Public Sub DisposeImp() Implements IDisposable.Dispose
            Console.WriteLine("Boo.IDisposable::Dispose")
        End Sub

        Public Shadows Sub Dispose()
            Console.WriteLine("Boo::Dispose()")
        End Sub

    End Class

    ''' <summary>
    ''' Неявно реализует интерфейс
    ''' </summary>
    Class Doo
        Inherits Foo

        ''' <summary>
        ''' Переопределение явной реализации
        ''' </summary>
        Public Overrides Sub DisposeImp()
            Console.WriteLine("Doo.IDisposable::Dispose")
        End Sub

        ''' <summary>
        ''' Неявное перекрытие
        ''' </summary>
        Public Sub Dispose()
            Console.WriteLine("Doo::Dispose()")
        End Sub

    End Class

    Sub Main()
        Dim foo As New Foo
        Dim boo As New Boo
        Dim doo As New Doo

        CType(foo, IDisposable).Dispose()
        foo.Dispose()
        CType(boo, IDisposable).Dispose()
        boo.Dispose()
        CType(doo, IDisposable).Dispose()
        doo.Dispose()
    End Sub

IDisp прадназначен для детерменированного освобождения как можно быстрее

На всех собеседованиях мы же хотели услышать (как мне кажется) от кандидата еще и то, что IDisp прадназначен для а) детерминированного освобождения и, как следствие б) освобождения ресурса на столько быстро, на сколько это возможно

StructLayout example

Возможно, этот пример Вас заинтересует.

    public class CustomClass
    {
        public virtual MyClass Field { get; set; }
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct CustomStructLayoutStruct
    {
        [FieldOffset(0)]
        public CustomClass something;

        [FieldOffset(0)]
        public string str;
    }

    class Program
    {
        static void Main(string[] args)
        {
            CustomStructLayoutStruct customStructLayoutStruct = new CustomStructLayoutStruct();
            customStructLayoutStruct.something = new CustomClass();
            customStructLayoutStruct.str = "4";
            Console.WriteLine($"customStructLayoutStruct.something.GetType(): {customStructLayoutStruct.something.GetType()}");//System.String
            Console.WriteLine($"customStructLayoutStruct.something: {customStructLayoutStruct.something}");//4
            Console.WriteLine($"customStructLayoutStruct.something.Field: {customStructLayoutStruct.something.Field}");//null
            Console.WriteLine($"customStructLayoutStruct.str: {customStructLayoutStruct.str}");//4
        }
    }

Данное поведение наблюдается лишь при виртуальном свойстве.

Конвенция именования статей и содержания

Предлагаю придерживаться того, что содержание и название заголовков и подзаголовков статей совпадают:

Содержание

  • Работа CLR
    • Память
      • Стек

Название статьи: вариант # 1

Работа CLR

Память

Стек


Название статьи: вариант # 2

Работа CLR. Память. Стек


Отображать можно по-разному, лишь бы было совпадение иерархии и названия в том или в ином виде.

Шаблон Lifetime

В продолжении главы про шаблон Disposable необходимо расписать работу и идеологию шаблона Lifetime

[Proposal] Handling special exceptions

Здравствуйте! Привожу ссылку на доклад Евгения Пешкова — Особые исключения в .NET:
https://www.youtube.com/watch?v=WLSrYgMWif4

В котором рассматриваются особенности каждого типа исключений, например: StackOverflowException, ThreadAbortException, AccessViolationException и OutOfMemoryException.

Думаю, имеет смысл упомянуть в книге о данных исключениях и способах их обработки.

#13

Disposable

"Финализатор, в отличии от деструктора, вызовется гарантированно, тогда как деструктор может и не вызваться"
После данной фразы кто-то возможно подумает, что он и правда вызывается абсолютно всегда. Но как вы сами указали (при OutOfMemoryException) вызывается финализатор не всегда. Просто немного противоречат эти 2 фразы. Возможно, стоит как-то по-другому сформулировать. Ну и возможно можно добавить еще 2 случая, когда он не вызывается: при завершении процесса время выполнения финализатора ограничивается примерно 2.2-2.3 секундами(число выясненно имперически, возможно оно в действительности несколько отличается) и вроде суммарное время выполнения всех финализаторов около 40сек, а также когда процесс жестоко убивают(например из TaskManager).

Также возможно Вы посчитаете не лишним добавить как пример к части про события и утечки памяти пример кастомного события, который не страдает данной проблемой

private class CustomDelegateWithWeakReference 
{
    public WeakReference TargetInstance { get; set; }
    public MethodInfo Action { get; set; }
}

Что-то такое, допустим. Возможно, Вы посчитаете, что в этой главе он лишний, но мне сложно это определить.

[Disposable] Внести уточнения по исключениям

Но стоит заметить, что вовсе не обязательно приложение падает с такого исключения, см. пример на скорую

Мне кажется, что тут в принципе стоит заметить, как себя ведёт приложение при различных исключениях:
StackOverflowException — приложение падает в нуль и без кетчей. Чтобы избежать такого — можно чекать стек через RuntimeHelpers.EnsureSufficientExecutionStack
ThreadAbortException — ловится в catch, но пробрасывается выше
OutOfMemoryException — ловится в кетч, если по факту памяти уже достаточно, то приложение продолжает работу
ExecutionEngineException — что-то не так в самом CLR пошло

Подробнее см. Exceptional Exceptions in .NET

[Disposable] Неявный boxing

Несмотря на то что неявный boxing - удел C#, а не .NET, стоит рассказать и об этом.

Нужность / ненужность финализатора

Когда я только начал читать, у меня в памяти всплыло что этот интерфейс предназначен для освобождения как управляемых ресурсов, которые надо освобождать, так и для неуправляемых. Именно по этому в шаблоне есть две ветки исполнения. И именно по этому возникает вопрос про нужность/ненужность финализатора.

Поначалу ты говоришь что он создан для освобождения неуправляемых ресурсов

Поначалу ты говоришь что он создан для освобождения неуправляемых ресурсов, и большая часть текста делает на этом акцент. Но в конце ты говоришь "по этому и агрегирующие классы должны реализовывать IDis".

Virtual method performance

"Вызов виртуальных методов хоть и идет через таблицу VMT, но из-за того что индексы заранее известны, то по сути каждый вызов нагружается на единственное разыменовывание указателя. В 99,999% случаев это не повлияет вообще ни на что: проседание (если вообще можно так выразиться) будет настолько маленьким что им в принципе можно принебречь"
По сравнению с невиртуальными методами, проседание все же будет не таким незначительным, т.к. насколько я помню, при вызове невиртуальных методов нет необходимости в разыменовании указателя на таблицу методов, т.к. есть возможность вызвать метод напрямую.
Также виртуальный метод автоматически убирает возможность мощной оптимизации - встаивания метода, что логично, т.к. тип объекта становится известным только во время выполнения.

Глава Исключения

Здесь я предлагаю вести обсуждение главы Исключения. Ошибки, дополнения.

[Disposable] Уточнить вопрос, что имелось ввиду под "некомпетентностью"

Думаю, что называть это некомпетентностью все же не верно. Ведь освобождение ресурсов в «правильном» порядке без повторов по сути ничего не дает. А отсутствие необходимости думать об этом дает довольно много. В 1-ую очередь повышает скорость разработки и надежность.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.