<?xml version="1.0" encoding="utf-8"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>Форум программистов и сисадминов Киберфорум - Блоги - netBool</title>
		<link>https://www.cyberforum.ru/blogs/125422/</link>
		<description>КиберФорум - форум программистов, системных администраторов, администраторов баз данных, компьютерный форум, форум по электронике и бытовой технике, обсуждение софта. Бесплатная помощь в решении задач по программированию и наукам, решение проблем с компьютером, операционными системам</description>
		<language>ru</language>
		<lastBuildDate>Tue, 22 Sep 2026 08:56:01 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>60</ttl>
		<image>
			<url>https://www.cyberforum.ru//cyberstatic.net/images/misc/rss.jpg</url>
			<title>Форум программистов и сисадминов Киберфорум - Блоги - netBool</title>
			<link>https://www.cyberforum.ru/blogs/125422/</link>
		</image>
		<item>
			<title><![CDATA[Xamarin.Forms.Xaml.XamlParseException: Cannot assign property "Content"...]]></title>
			<link>https://www.cyberforum.ru/blogs/125422/5472.html</link>
			<pubDate>Fri, 28 Sep 2018 07:00:24 GMT</pubDate>
			<description>Давно хотел попробовать Xamarin. Эта удивительная штука, которая позволяет довольно быстро...</description>
			<content:encoded><![CDATA[<div>Давно хотел попробовать Xamarin. Эта удивительная штука, которая позволяет довольно быстро разрабатывать приложения. Конечно, отличие от обычного WinForms/WPF довольно серьезное. Первое, что вас может удивить (а может и разочаровать), что у классов и методов нет подсказок в Intellisense. Нет. нет.. сам автокомплит есть, но вот без подсказок: кто-то поленился расставить комментарии к коду:)<br />
<br />
Ну это так, мелочи. Поговорить в этой заметке я бы хотел об одной ошибке, с которой столкнулся и не нашел ее отзвуков в сети: <br />
я создал новый проект Xamarin.Forms, хотел его откомпилировать и получил<br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">Xamarin.Forms.Xaml.XamlParseException: Cannot assign property &quot;Content&quot;: Property does not exists, or is not assignable, or mismatching type between &gt;value and property</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Чудно<br />
<br />
На оф сайте на самом деле есть <a rel="nofollow noopener noreferrer" href="https://forums.xamarin.com/discussion/113994/how-to-debug-xamarin-forms-xaml-xamlparseexception-cannot-assign-property-content" target="_blank" title="https://forums.xamarin.com/discussion/113994/how-to-debug-xamarin-forms-xaml-xamlparseexception-cannot-assign-property-content">решение </a> этой проблемы<br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">So make sure that between elements there are not any characters as this might lead to the exception you mentioned. i.e</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>И там проблема была в лишней запятой в xaml файле, которая упрямо пряталась от глаз<br />
<br />
Собственно мой xaml новорожденного проекта выглядел сложнее некуда: <br />
<div class="codeblock"><table class="xml"><thead><tr><td colspan="2" id="726587141"  class="head">XML</td></tr></thead><tbody><tr class="li1"><td><div id="726587141" style="height: 174px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
</pre></td><td class="de1"><pre class="de1"><span class="sc3"><span class="re1">&lt;?xml</span> <span class="re0">version</span>=<span class="st0">&quot;1.0&quot;</span> <span class="re0">encoding</span>=<span class="st0">&quot;utf-8&quot;</span> <span class="re2">?&gt;</span></span>
<span class="sc3"><span class="re1">&lt;ContentPage</span> <span class="re0">xmlns</span>=<span class="st0">&quot;http://xamarin.com/schemas/2014/forms&quot;</span></span>
<span class="sc3"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">xmlns:x</span>=<span class="st0">&quot;http://schemas.microsoft.com/winfx/2009/xaml&quot;</span></span>
<span class="sc3"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">xmlns:local</span>=<span class="st0">&quot;clr-namespace:FastTask&quot;</span></span>
<span class="sc3"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">x:Class</span>=<span class="st0">&quot;FastTask.MainPage&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; ****
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Button</span> <span class="re0">x:Name</span>=<span class="st0">&quot;button1&quot;</span> <span class="re0">Text</span>=<span class="st0">&quot;Нажать!&quot;</span> <span class="re0">Clicked</span>=<span class="st0">&quot;Button_Click&quot;</span> <span class="re2">/&gt;</span></span> **** 
&nbsp;
<span class="sc3"><span class="re1">&lt;/ContentPage<span class="re2">&gt;</span></span></span></pre></td></tr></table></div></td></tr></tbody></table></div>Я все глаза проглядел в поисках невидимых &quot;запятых&quot;:), которых так и не оказалось. Но знаете, что. Аналогичный код. скопипастеный из урока на метаинит не выдавал ошибок. Так то<br />
<br />
Если вы считаете себя мастером  C# и xaml, то можете написать в комментариях очевидную ошибку, которую я допустил, а затем открыть спойлер :) <br />
<br />

			   <div class="spoiler-wrap">
				   <div class="spoiler-head folded clickable">Кликните здесь для просмотра всего текста</div>
				   <div class="spoiler-body">
					   <br />
<br />
После 10 попыток увидеть невидимое, я решил сравнить текст посимвольно. Мне было лень открыть систему контроля версий для такой мелочи и я воспользовался первым попавшимся мне сервисом для сравнения текстов <a rel="nofollow noopener noreferrer" href="http://text.num2word.ru/" target="_blank" title="http://text.num2word.ru/">онлайн</a>. Готовы? Так вот оказалось, в моем случае проблема была в лишних пробелах после ContentPage. Удалил и вуаля!<br />
<br />

				   </div>
			   </div><br />
<br />
Всем удачи)</div>

]]></content:encoded>
			<dc:creator>netBool</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/125422/5472.html</guid>
		</item>
		<item>
			<title>С++ глазами шарпийца</title>
			<link>https://www.cyberforum.ru/blogs/125422/5300.html</link>
			<pubDate>Fri, 15 Jun 2018 09:14:05 GMT</pubDate>
			<description>Доброго дня!  
 
C++ и C# очень похожие языки, но под капотом имеют совершенно разные подход и...</description>
			<content:encoded><![CDATA[<div>Доброго дня! <br />
<br />
C++ и C# очень похожие языки, но под капотом имеют совершенно разные подход и философию. <br />
И я хотел бы отметить несколько особенностей и трудностей, с которыми обязательно столкнется честный шарпиец при переходе на C++<br />
<br />
<b>1. Массив char и const char*</b><br />
<br />
Например, нужно соединить два массива char. C++ унаследовало для этого от Си замечательную функцию strcat<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="562873494"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="562873494" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw4">char</span> <span class="sy2">*</span> <span class="kw3">strcat</span><span class="br0">&#40;</span> <span class="kw4">char</span> <span class="sy2">*</span> destptr, <span class="kw4">const</span> <span class="kw4">char</span> <span class="sy2">*</span> srcptr <span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>По стандарту функция добавляет к destptr массив srcptr и возвращает уже соединенный массив destptr <br />
<br />
Честный шарпиец знает, что такое типы данных. И с точки зрения шарпа вполне правильно будет написать так: <br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="815079833"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="815079833" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1"><span class="kw4">char</span><span class="sy2">*</span> a <span class="sy1">=</span> <span class="st0">&quot;be&quot;</span><span class="sy4">;</span>
<span class="kw4">const</span> <span class="kw4">char</span> <span class="sy2">*</span>b <span class="sy1">=</span> <span class="st0">&quot;gin&quot;</span><span class="sy4">;</span>
<span class="kw3">strcat</span><span class="br0">&#40;</span>a,b<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Ну и что? Вы думаете сработало? Не тут-то было!<br />
<b>Почему?????</b> - спросите вы. Типы данных совпадают с сигнатурой. <code class="inlinecode">#include &lt;cstring&gt;</code> подключен. Но ошибка ... <br />
<br />
<b>Давайте разбираться:</b> <br />
Во-первых, первый аргумент - это массив в C++, который должен вмещать другой массив. А значит его размер должен быть не меньше размера массива второго аргумента<br />
<br />
&quot;Ок.&quot; - скажете вы. Делаем так:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="968286335"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="968286335" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; <span class="kw4">char</span><span class="sy2">*</span> a <span class="sy1">=</span> <span class="kw3">new</span> <span class="kw4">char</span><span class="br0">&#91;</span><span class="nu0">5</span><span class="br0">&#93;</span><span class="sy4">;</span><span class="co1">//сделали размер массива *a - 5 байт</span>
&nbsp; &nbsp; a<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="sy1">=</span><span class="st0">'b'</span><span class="sy4">;</span>
&nbsp; &nbsp; a<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="sy1">=</span><span class="st0">'e'</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">const</span> <span class="kw4">char</span> <span class="sy2">*</span>b <span class="sy1">=</span> <span class="st0">&quot;gin&quot;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">char</span><span class="sy2">*</span> cr <span class="sy1">=</span> <span class="kw3">strcat</span><span class="br0">&#40;</span>a,b<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Два первых символа проинициализировали, еще три добавили. Профит. Ошибки не выдает<br />
<br />
Не тут то было8-). Загляните в отладчик. У меня cr равен <code class="inlinecode">beНННээээ««««««««юоюоюоюgin</code>. А у вас?<br />
<br />
Не буду забегать вперед. Причины такого поведения я подробно опишу во втором пункте. Сейчас же коснусь только кратко: решением будет <br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="645429698"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="645429698" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="sy2">*</span><span class="br0">&#40;</span>a<span class="sy2">+</span><span class="nu0">2</span><span class="br0">&#41;</span> <span class="sy1">=</span> <span class="st0">'<span class="es5">\0</span>'</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>перед вызовом <code class="inlinecode">strcat</code>. Дело в том, что функция strcat ищет символ '\0', который для нее обозначает конец [const] char* строки и начиная с него вставляет новые символы из второго аргумента srcptr <br />
<br />
Хм, скажете вы. Что ж, тогда должна работать и такая схема: <br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="834637424"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="834637424" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw4">char</span> <span class="sy2">*</span>a <span class="sy1">=</span> <span class="st0">&quot;be<span class="es5">\0</span>&quot;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Но и тут вы получите разочарование. Почему? <br />
<br />
<br />
Любопытно, что на этот вопрос честно и откровенно не могут ответить даже многие программисты с++-стека. Как правило, они ограничиваются ответом типа: <code class="inlinecode">ну вы же не выделили память под 5 байт, как сказано в документации. А значит для копирования просто не хватает памяти</code>. Да, не выделили. Это правда, но не вся. Если бы это была вся правда, то работала бы такая конструкция: <br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="984215072"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="984215072" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw4">char</span> <span class="sy2">*</span>a <span class="sy1">=</span> <span class="st0">&quot;be<span class="es5">\0</span>mmm&quot;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>В ней мы получили указатель под массив 6 байт. Копируй себе на здоровье)) <br />
Но нет. Мы получим что? <br />
Правильно, ошибку. И вот тут, как правило, логика с++ заканчивается. <br />
<br />
Более полная картина получается, если мы посмотрим, куда распределяется память. Дело в том. что при объявлении <br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="137415526"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="137415526" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw4">char</span><span class="sy2">*</span> a <span class="sy1">=</span> <span class="st0">&quot;be<span class="es5">\0</span>mmm&quot;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Под &quot;be\0mmm&quot; при <b>компиляции </b> будет выделена память в секции строковых констант (как правило, она называется edata или data), которая при запуске приложения помещается в памяти с флагом readonly. Короче, иными словами в этом случае переменная a по сути указывает на константу, <a href="https://www.cyberforum.ru/cpp-beginners/thread2257113.html#post12441242">то есть является типом const char*, несмотря на то, что объявлен char*</a>.<br />
<br />
То есть вариант с <code class="inlinecode">char *a = &quot;&quot;;</code> не будет работать ни при каких условиях, что бы не было написано внутри скобок<br />
<br />
Короче пишешь один тип - получаешь другой. Вот за что я люблю шарп? Там только в страшном сне такое присниться..<br />
<br />
Как же правильно работать с массивами char в c++? Я думаю, вам понравится такой вариант: <br />
<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="11697682"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="11697682" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; <span class="kw4">char</span> a<span class="br0">&#91;</span><span class="nu0">5</span><span class="br0">&#93;</span> <span class="sy1">=</span> <span class="st0">&quot;be&quot;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">const</span> <span class="kw4">char</span> <span class="sy2">*</span>b <span class="sy1">=</span> <span class="st0">&quot;gin&quot;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">char</span><span class="sy2">*</span> cr <span class="sy1">=</span> <span class="kw3">strcat</span><span class="br0">&#40;</span>a,b<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Чего?? - скажете честный шарпиец. <code class="inlinecode">char&#91;5&#93;</code> и <code class="inlinecode">char*</code> - <b>это разные типы данных</b>. Сигнатура strcat требует именно <code class="inlinecode">char*</code>, а не <code class="inlinecode">char&#91;&#93;</code>. Почему же она выдает ошибку на тот тип, который требует и работает с тем, который не указан в сигнатуре? <br />
<br />
:pardon: Ну вот так. Все неочевидно<br />
<br />
Вывод: в с++ важно смотреть <a rel="nofollow noopener noreferrer" href="http://www.cplusplus.com/reference/cstring/strcat/" target="_blank" title="http://www.cplusplus.com/reference/cstring/strcat/">документацию</a>. В C# есть очень последовательная и строгая философия: главное соблюсти условия сигнатуры функции и получишь правильный результат и при этом не обязательно знать, что творится под капотом. В С++ же просто необходимо знать, как и где переменные, массивы и объекты распределяются в памяти. Должен вам сказать, что некоторые ошибки в C++ у меня получалось отлавливать только с помощью OllyDbg - c такими ошибками  в C# студия бы даже не позволила откомпилировать, но четко указала бы строку с ошибкой и тип ошибки... Но об этом позже<br />
<br />
<b>2. Массив char</b><br />
<br />
В Си/С++ есть массивы. Это знают все. Но что будет, если мы объявим массив <code class="inlinecode">char a&#91;16&#93;;</code>. В C# подобное объявление <code class="inlinecode">char&#91;16&#93; a;</code> означало бы неинициализированный массив и до инициализации работа с ним была бы невозможна. В C/С++ <code class="inlinecode">a</code> при объявлении выделяет память на стеке - смещает ESP-регистр на 16 байт, при чем эти 16 байт могут быть заполнены всякой аброкадаброй либо случайным символом. И что еще? А больше ничего... Иногда это приводит к таким интересным казусам: <br />
<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=4872&amp;d=1529155931" rel="Lightbox" id="attachment4872" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=4872&amp;thumb=1&amp;d=1529155931" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: Безымянный.png
Просмотров: 828
Размер:	243.6 Кб
ID:	4872" style="margin: 5px" /></a><br />
<br />
Неожиданно?<br />
<br />
Как видно из картинки был объявлен массив <code class="inlinecode">act_key </code> размером 16 байт и не заполнен, но в отладке он уже 24 байта и заполнен символом &quot;M&quot;. Любопытно, правда? <br />
<br />
То есть объявление массива даже не добавляет никакого флага в памяти, чтобы обозначить его границы и, например, <code class="inlinecode">strlen(a)</code>  вернет неверное значение (в этом случае верное значение вернет <font color="blue">sizeof</font>, но это другая тема). В этом кстати и есть отличие, единственное и неповторимое, между Си-строкой и массивом char: <br />
<br />
если мы объявим: <code class="inlinecode">char* a=&quot;aaa&quot;;</code> - это будет строка, тк в таком исполнении компилятор добавит по адресу <code class="inlinecode">a+3</code> значение '\0', означающее конец строки (массива) и strlen вернет верное значение. Если же объявить <code class="inlinecode">char*a={'a','a','a'}</code> - то границы у этого массива уже не будет<br />
<br />
<b>3 Заполнение массива по умолчанию</b><br />
<br />
Немного еще о неочевидным вещах. В C++ можно заполнить массив значением по умолчанию при инициализации. Выглядит это вот так:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="951088930"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="951088930" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw4">char</span> a<span class="br0">&#91;</span><span class="nu0">16</span><span class="br0">&#93;</span><span class="sy1">=</span><span class="br0">&#123;</span><span class="nu0">0</span><span class="br0">&#125;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Очевидно, что все 16 байт заполнятся нулями. Такого, насколько знаю, даже в шарпе нет.... С таким синтаксисом, казалось бы, можно свернуть горы: <br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="706033365"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="706033365" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw4">char</span> a<span class="br0">&#91;</span><span class="nu0">16</span><span class="br0">&#93;</span><span class="sy1">=</span><span class="br0">&#123;</span><span class="nu0">25</span><span class="br0">&#125;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>И все <s>16 символов</s> только первый символ будет иметь значение 25. Как-то так.. :) Не верите? Попробуйте сами<br />
<br />
<b>4. Обработка исключений</b><br />
<br />
В c++ нет нормальной обработки исключений. Это надо просто принять. <br />
<br />
Здесь все исключения можно разделить на две группы: исключения с++ и системные исключения<br />
<br />
Классическая для C#(/java/python) конструкция: try/catch ловит только исключения c++. Вы скажете - есть же __try/__except! Верно, но это не входит в спецификацию C++, это исключительное введение Microsoft под Visual-C++ и Windows. Быть может, если это ваш стек, то разницы вы не заметите, но какая ж тут кроссплатформенность?<br />
<br />
<b>Есть </b> решение в виде POSIX-сигналов, как описано в этой <a rel="nofollow noopener noreferrer" href="https://habr.com/post/131412/" target="_blank" title="https://habr.com/post/131412/">статье</a>. Я проверил, под винду работает. Но получилось у меня это воспроизвести только в том виде, как у автора статьи, с выходом из программы, а мне, например, надо было в случае ошибки, обработать ее и продолжить работу программы дальше. Если убрать строчку<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="73944219"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="73944219" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw3">exit</span><span class="br0">&#40;</span><span class="nu0">3</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Мы получим системную ошибку в <code class="inlinecode">fall();</code>. На этом обработка ошибок заканчивается<br />
<br />
<br />
<b>5. sizeof</b><br />
<br />
В С++ <font color="Blue">sizeof</font> может возвращать размер не только типа <code class="inlinecode">sizeof(int)</code>, но и переменной (и даже объекта на стеке!), например: <br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="620597437"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="620597437" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1"><span class="kw4">int</span> c<span class="sy1">=</span><span class="nu0">4</span><span class="sy4">;</span>
<span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Очень часто в интернете встречался вопрос, как определить длину массива в С++. Ответ на этот вопрос не совсем однозначный, тк в С++ все массивы делятся на статические (<code class="inlinecode">char c&#91;3&#93; = &quot;aaa&quot;</code>) и динамические <code class="inlinecode">char *c = new char&#91;3&#93;</code>.<br />
длину статического массива можно определить как <br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="417192160"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="417192160" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1"><span class="kw4">char</span> c<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span> <span class="sy1">=</span> <span class="st0">&quot;aaa&quot;</span><span class="sy4">;</span>
<span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><span class="sy2">/</span><span class="kw3">sizeof</span><span class="br0">&#40;</span><span class="sy2">*</span>c<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>А вот динамического - никак, поскольку sizeof вернет всего лишь размер указателя. Поэтому с необходимо либо иметь какой-то флаг, означающий конец массива,либо передавать размер массива в функцию вместе с указателем на него (немного костляво, но вот оно, низкоуровневое программирование)<br />
<br />
<b>6. Инициализация объекта</b><br />
<br />
Инициализация объекта в С++ происходит немного не так, как в шарпе. Возьмем два класса:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="760088753"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="760088753" style="height: 126px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
</pre></td><td class="de1"><pre class="de1"><span class="kw2">class</span> A
<span class="br0">&#123;</span>
<span class="kw2">public</span><span class="sy4">:</span>
&nbsp; &nbsp; <span class="kw4">int</span> b<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> c<span class="sy4">;</span>
<span class="br0">&#125;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div><div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="896807807"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="896807807" style="height: 142px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
</pre></td><td class="de1"><pre class="de1"><span class="kw2">class</span> B
<span class="br0">&#123;</span>
<span class="kw2">public</span><span class="sy4">:</span>
&nbsp; &nbsp; B<span class="br0">&#40;</span><span class="kw4">int</span> c<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> b<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> c<span class="sy4">;</span>
<span class="br0">&#125;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Их инициализация на стеке будет отличатся. Для B это будет <code class="inlinecode">B b(1)</code> (Похоже на вызов функции в C#, правда?). А вот инициализация типа A подобным образом <code class="inlinecode">A a()</code> вызовет ошибку. В С++ правильная инициализация типа с конструктором без параметров будет выглядеть <code class="inlinecode">A a;</code> и подобна обычному объявлению примитивной переменной. В то же время инициализация в куче через new будет выглядеть <code class="inlinecode">A *a = new A();</code><br />
<br />
<b>7. Приведение типов</b><br />
В C# мы привыкли приводить типы как-то так:<br />
<div class="codeblock"><table class="csharp"><thead><tr><td colspan="2" id="345938970"  class="head">C#</td></tr></thead><tbody><tr class="li1"><td><div id="345938970" style="height: 254px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="de1"><pre class="de1"><span class="kw4">class</span> A <span class="sy0">:</span> B
<span class="br0">&#123;</span>
&nbsp;
<span class="br0">&#125;</span>
<span class="kw4">class</span> B
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">int</span> c<span class="sy0">;</span>
<span class="br0">&#125;</span>
<span class="co1">//...</span>
A func<span class="br0">&#40;</span>A a<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="br0">&#40;</span><span class="br0">&#40;</span>B<span class="br0">&#41;</span>a<span class="br0">&#41;</span><span class="sy0">.</span><span class="me1">c</span> &nbsp;<span class="sy0">=</span><span class="nu0">5</span><span class="sy0">;</span>
&nbsp; &nbsp; <span class="kw1">return</span> a<span class="sy0">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Пример примитивный и не имеет практической ценности. Он взят просто для показательности. Функция вернет объект <code class="inlinecode">A</code> с полем <code class="inlinecode">c</code>=5<br />
<br />
C++ же подобный код заработает только если мы работаем с указателем: <br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="718944018"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="718944018" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1">A <span class="sy2">*</span>func<span class="br0">&#40;</span>A <span class="sy2">*</span>a<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="br0">&#40;</span><span class="br0">&#40;</span>B<span class="sy2">*</span><span class="br0">&#41;</span>a<span class="br0">&#41;</span><span class="sy2">-</span><span class="sy1">&gt;</span>c &nbsp;<span class="sy1">=</span><span class="nu0">5</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">return</span> a<span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Функция вернет указатель на объект <code class="inlinecode">A</code> с полем <code class="inlinecode">c</code> = 5<br />
Но если сделать в стиле C#, например, так: <br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="457752840"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="457752840" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1">A func<span class="br0">&#40;</span>A a<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="br0">&#40;</span><span class="br0">&#40;</span>B<span class="br0">&#41;</span>a<span class="br0">&#41;</span>.<span class="me1">c</span> &nbsp;<span class="sy1">=</span><span class="nu0">5</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">return</span> a<span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Функция вернет a, но значение поля <code class="inlinecode">c</code> <s>будет равно 5</s> не изменится, поскольку в С++ при таком приведении в <code class="inlinecode">(B)a</code> создается новый объект-копия a типа B и именно ему мы меняем значение поля c.<br />
<br />
<b>8. i = ++i + ++i</b><br />
Возьмем простейший код:<br />
<div class="codeblock"><table class="csharp"><thead><tr><td colspan="2" id="723477772"  class="head">C#</td></tr></thead><tbody><tr class="li1"><td><div id="723477772" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1"><span class="kw4">int</span> i<span class="sy0">=</span><span class="nu0">5</span><span class="sy0">;</span>
i <span class="sy0">=</span> <span class="sy0">++</span>i <span class="sy0">+</span> <span class="sy0">++</span>i<span class="sy0">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Для C# очевидно, что i вернет 13: 13 = 6 + 7;<br />
Весь код выполняется последовательно<br />
<br />
Но в C++ это будет <a rel="nofollow noopener noreferrer" href="http://lurkmore.to/%2B%2Bi_%2B_%2B%2Bi" target="_blank" title="http://lurkmore.to/%2B%2Bi_%2B_%2B%2Bi">ub</a>!<br />
<br />
<b>9. Массивы</b><br />
Не удивляйтесь, если вы увидите в исходниках<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="100678339"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="100678339" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1"><span class="kw4">int</span> a<span class="br0">&#91;</span><span class="nu0">10</span><span class="br0">&#93;</span><span class="sy4">;</span>
<span class="nu0">9</span><span class="br0">&#91;</span>a<span class="br0">&#93;</span><span class="sy1">=</span><span class="nu0">0</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Дело в том. что в C++ доступ к элементам массива можно осуществлять не только так <code class="inlinecode">a&#91;n&#93;</code>, но и так <code class="inlinecode">n&#91;a&#93;</code>. То же самое<br />
<br />
<br />
<b>Итоги</b><br />
<br />
Может быть, встречу еще какие-нибудь любопытные особенности. В целом С++ очень мощный инструмент (чего нельзя сказать об IDE для него). В нем есть много крутых штук, которых нет в C#, например, friend-классы и множественное наследование и много других штук, а так же, конечно, возможность работы непосредственно с памятью. Благодаря этому язык С++ очень гибкий. Но в нем вы не найдете аналога Extension (кому-то может показаться, что это что-то наподобие friend, но это не так), а так же нет нормального Reflection-а (и скорее всего его никогда там не будет, поскольку это потребует огромный слой кода, чтобы преодолеть кросскомпиляторность. Ее проще реализовать для каждого компилятора отдельно, чем заносить в стандарт). Но самое главное, чего нет в С++ (на мой имхо взгляд), что существенно снижает скорость разработки в 5 раз - это нормальная обработка ошибок, точнее ее отсутствие. Например, после шарпа я три дня потратил на поиск ошибок в простом коде функции перехвата другой функции с сигнатурой <code class="inlinecode">void (*)(int)</code><br />
<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="310433401"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="310433401" style="height: 94px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
</pre></td><td class="de1"><pre class="de1"><span class="kw4">void</span><span class="sy2">*</span> MyFunc<span class="br0">&#40;</span><span class="kw4">int</span> c<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> c<span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>(на самом деле тело метода состояло из сотни строк кода, но я их убрал для показательности). Это была обычная невнимательность: я привык, что в C# все, что начинается c <code class="inlinecode">void</code> не возвращает значение. И знаете, ребята, если бы я допустил такую оплошность в шарпе, то студия даже компилироваться отказалась и написала бы мне строку и тип ошибки, кот. я допустил. Но тут все скомпилировалось. Мало того! Даже эта функция отрабатывала без ошибок! А ошибка возникала где-то после нее... Неудивительно, что я искал ее три дня...:) <br />
<br />
Так что будьте осторожны...<br />
<br />
Всем добра</div>

]]></content:encoded>
			<dc:creator>netBool</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/125422/5300.html</guid>
		</item>
		<item>
			<title>Заметки про C#. А знали ли вы?</title>
			<link>https://www.cyberforum.ru/blogs/125422/5250.html</link>
			<pubDate>Tue, 08 May 2018 09:29:54 GMT</pubDate>
			<description>Погружаясь в леса и дебри Reflection и IL, постепенно узнаю много новых вещей о .NET, о которых...</description>
			<content:encoded><![CDATA[<div>Погружаясь в леса и дебри Reflection и IL, постепенно узнаю много новых вещей о .NET, о которых раньше даже не задумывался. И хотел бы поделиться некоторыми из них (буду дописывать по мере наличия свободного времени): <br />
<br />
<b>1. Тип void</b><br />
Знали ли вы, что в C# <b>void </b> - не просто ключевое слово для обозначения функции, не возвращающей значение, а полноценных тип данных?<br />
<br />
Да, да. Несколько фактов о нем: <ul><li>В С# нельзя просто так объявить экземпляр типа void. Сам тип можно получить через typeof(void)</li>
<li>Тип void подобен структуре: этот тип не является примитивом, но в то же время считается значимым типом</li>
<li>В C#, как в С++, нельзя разыменовать void:<s>*void</s>, несмотря на то, что он является значимым типом. По сути void* - не что иное, как неуправляемый аналог IntPtr</li>
</ul><br />
<b>2. Делегаты</b><br />
<br />
На уровне IL все - классы, интерфейсы, структуры и даже делегаты - все является классами. Но делегаты выделяются из всей этой кучи. Delegate - это особый класс в .NET Framework. Он не объявлен как sealed, но мы не можем явно наследовать от него свои классы (так же, как и от <a rel="nofollow noopener noreferrer" href="https://msdn.microsoft.com/ru-ru/library/system.multicastdelegate(v=vs.110).aspx" target="_blank" title="https://msdn.microsoft.com/ru-ru/library/system.multicastdelegate(v=vs.110).aspx">MulticastDelegate</a>). Но когда мы пишем <br />
<div class="codeblock"><table class="csharp"><thead><tr><td colspan="2" id="478784080"  class="head">C#</td></tr></thead><tbody><tr class="li1"><td><div id="478784080" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw4">delegate</span> <span class="kw4">void</span> EmptyDelegate<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Мы на самом деле объявляем класс, унаследованный от Delegate и MulticastDelegate.<br />
<br />
<b>3. Исходники</b><br />
<br />
Майкрософт выложила исходный код <a rel="nofollow noopener noreferrer" href="https://referencesource.microsoft.com/" target="_blank" title="https://referencesource.microsoft.com/">.NET Framework</a>, а так же компилятора Roslyn, изъяв ото всюду старый нативный компилятор. И у многих программистов сложилось впечатление, что весь .NET написан на C#. Но мало кто заглядывал под капот: сам <a rel="nofollow noopener noreferrer" href="https://github.com/dotnet/coreclr/tree/3c28c423053f30adedc034c5e2c912bd2adaad10/src/jit" target="_blank" title="https://github.com/dotnet/coreclr/tree/3c28c423053f30adedc034c5e2c912bd2adaad10/src/jit">jit-компилятор</a>, &quot;<a rel="nofollow noopener noreferrer" href="https://github.com/dotnet/coreclr/tree/3c28c423053f30adedc034c5e2c912bd2adaad10/src/vm" target="_blank" title="https://github.com/dotnet/coreclr/tree/3c28c423053f30adedc034c5e2c912bd2adaad10/src/vm">виртуальная машина</a>&quot; и многое другое написаны на С++ и assembler, в том числе assembler ARM/ARMx64<br />
<br />
<b>4. Хранение больших объектов в памяти</b><br />
<br />
Принято считать, что CLR для ссылочных типов хранит только ссылку на объект, а сам под сам объект выделяется память где-то в куче. Но мало кто догадывается, поскольку об этом не пишут в учебниках, <a rel="nofollow noopener noreferrer" href="https://msdn.microsoft.com/ru-ru/library/dd335945.aspx#code-snippet-3" target="_blank" title="https://msdn.microsoft.com/ru-ru/library/dd335945.aspx#code-snippet-3">что</a><br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message"> CLR работает с объектами, размер которых больше или равен 85000 байтам, иначе, чем с объектами меньшего размера. Большие объекты создаются в Large Object Heap (LOH), а объекты меньшего размера — в обычной куче, GC Heap, что позволяет оптимизировать выделение памяти под объекты и сбор мусора. LOH не уплотняется, а GC Heap уплотняется при каждом сборе мусора. Кроме того, сбор мусора в LOH осуществляется только при полном сборе мусора.</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Вероятно, это и есть причина тому, что NET-программы, работающие с большими объемами данных в памяти, не успевают очищать ее. И этот тот самый момент, на который стоит уделить особое внимание разработчиков таких программ<br />
<br />
<b>5. IL-код</b><br />
Как мы знаем код C#, а так же VB.NET, и других .NET языков компилируется не в машинные инструкции, а в так называемый промежуточный байт-код, описываемый на языке MSIL. Подробное описание инструкций IL-ассемблера можно нати на <a rel="nofollow noopener noreferrer" href="https://msdn.microsoft.com/ru-ru/library/system.reflection.emit.opcodes(v=vs.110).aspx" target="_blank" title="https://msdn.microsoft.com/ru-ru/library/system.reflection.emit.opcodes(v=vs.110).aspx">msdn</a> в описании класса <font color="Blue">System.Reflection.Emit</font>.<font color="DeepSkyBlue">Opcodes</font>. Но следует знать, что там описаны только часть <a rel="nofollow noopener noreferrer" href="https://en.wikipedia.org/wiki/List_of_CIL_instructions" target="_blank" title="https://en.wikipedia.org/wiki/List_of_CIL_instructions">инструкций</a>. Например, там нет описания инструкций <font color="Blue">no</font> и <font color="Blue">break</font>.<br />
<br />
Получить .*il файл можно через командную строку разработчика, предварительно перейдя <code class="inlinecode">cd</code> в директорию в исполняемым файлом, и набрав <div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="399990705"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="399990705" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">ildasm file.exe /out=file.il</pre></td></tr></table></div></td></tr></tbody></table></div>Подробнее об опциях запуска ildasm можно почитать <a rel="nofollow noopener noreferrer" href="https://msdn.microsoft.com/library/f7dy01k1(v=vs.100).aspx" target="_blank" title="https://msdn.microsoft.com/library/f7dy01k1(v=vs.100).aspx">здесь</a><br />
<br />
Существуют так же способы <a rel="nofollow noopener noreferrer" href="http://www.vbstreets.ru/VB/Articles/66392.aspx" target="_blank" title="http://www.vbstreets.ru/VB/Articles/66392.aspx">отладки</a> непосредственно msil-кода<br />
<br />
<b>6. Инициализаторы модулей</b><br />
В .NET помимо статических конструкторов класса, можно так же задавать и <a rel="nofollow noopener noreferrer" href="https://habr.com/post/175185/" target="_blank" title="https://habr.com/post/175185/">статические конструкторы модулей</a>. К сожалению, в C# такой возможности нет, но к C#-проекту можно прикрутить статический конструктор модуля через ilasm. <br />
Его сигнатура будет выглядеть так: <br />
<div class="codeblock"><table class="csharp"><thead><tr><td colspan="2" id="909187965"  class="head">C#</td></tr></thead><tbody><tr class="li1"><td><div id="909187965" style="height: 94px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
</pre></td><td class="de1"><pre class="de1"><span class="sy0">.</span><span class="me1">method</span> assembly specialname rtspecialname <span class="kw1">static</span> <span class="kw4">void</span> &nbsp;<span class="sy0">.</span><span class="me1">cctor</span><span class="br0">&#40;</span><span class="br0">&#41;</span> cil managed
<span class="br0">&#123;</span>
&nbsp;
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Для чего это можно использовать, пока с трудом себе представляю. Но нюанс любопытный<br />
<br />
<b>7. Деструкторы</b><br />
В C#, как и в C++, есть деструкторы. Но играют совсем иную роль: разумеется, их нельзя вызвать принудительно, т.к. сборкой мусора в .NET занимается сборщик мусора. Но тем не менее, их можно использовать как событие, оповещающее о том, что объект удален GC, вместо проверки слабых ссылок<br />
<br />
<b>8. try/catch/finally</b><br />
Еще одной интересной особенностью C# и .NET в частности, является то, что для блок try/catch не имеет опкодов для реализации. Они задаются не через инструкции il, а в специальных блоках Exception внутри тела метода. Эти блоки не влияют на CodeSize метода! И тем удивительнее, что finally не указываются в этих блоках: для него есть специальный опкод <a rel="nofollow noopener noreferrer" href="https://msdn.microsoft.com/ru-ru/library/system.reflection.emit.opcodes.endfinally(v=vs.110).aspx" target="_blank" title="https://msdn.microsoft.com/ru-ru/library/system.reflection.emit.opcodes.endfinally(v=vs.110).aspx">endfinally</a>, по достижении которого передается управление обработчику исключений для прыжка на следующую после обработки блока инструкцию. <div class="smallfont offtopic" onmouseover="this.style.color='#000000';" onmouseout="this.style.color='#888888';">
				<p><b>Не по теме:</b></p>
				<p>Зная особенности такой конструкции, можно выполнять запутывание кода, на мой взгляд, похлеще, чем на чистом asm (но, конечно, местами в ущерб производительности). Тем более, что нормальных отладчиков msil-кода не существует</p>
				</div><br />
<br />
<b>9. Удивительная компиляция foreach</b><br />
При пересборке своего проекта столкнулся с удивительной ситуацией: <br />
<div class="codeblock"><table class="csharp"><thead><tr><td colspan="2" id="658950140"  class="head">C#</td></tr></thead><tbody><tr class="li1"><td><div id="658950140" style="height: 286px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span><span class="sy0">.</span><span class="me1">DeserilizeFromCass</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//создание категорий товаров в списке перемещения товара</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>folds<span class="sy0">.</span><span class="me1">Count</span> <span class="sy0">&gt;</span> <span class="nu0">0</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co2">#region Создание категорий в cbxFolders</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span>DFolder fold <span class="kw1">in</span> folds<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbxFolders<span class="sy0">.</span><span class="me1">Items</span><span class="sy0">.</span><span class="kw1">Add</span><span class="br0">&#40;</span>@fold<span class="sy0">.</span><span class="me1">Name</span><span class="sy0">.</span><span class="me1">ToString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbxFolders<span class="sy0">.</span><span class="me1">SelectedIndex</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co2">#endregion &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span><span class="sy0">.</span><span class="me1">ReadDemands</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Этот код компилятор преобразовал в следующие il-код:<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="869587045"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="869587045" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
</pre></td><td class="de1"><pre class="de1"><span class="nu0">564</span> &nbsp; &nbsp; &nbsp;L_07ab<span class="sy1">:</span>&nbsp; &nbsp; ldarg<span class="sy1">.</span>0 
<span class="nu0">565</span> &nbsp; &nbsp; &nbsp;L_07ac<span class="sy1">:</span>&nbsp; &nbsp; <span class="kw1">call</span>&nbsp; &nbsp; System<span class="sy1">.</span>Void ForReady<span class="sy1">.</span>frmMain<span class="sy1">::</span>DeserilizeFromCass<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">566</span> &nbsp; &nbsp; &nbsp;L_07b1<span class="sy1">:</span>&nbsp; &nbsp; ldarg<span class="sy1">.</span>0 
<span class="nu0">567</span> &nbsp; &nbsp; &nbsp;L_07b2<span class="sy1">:</span>&nbsp; &nbsp; ldfld &nbsp; ForReady<span class="sy1">.</span>DFolders ForReady<span class="sy1">.</span>frmMain<span class="sy1">::</span>folds
<span class="nu0">568</span> &nbsp; &nbsp; &nbsp;L_07b7<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>Int32 System<span class="sy1">.</span>Collections<span class="sy1">.</span>Generic<span class="sy1">.</span>List`<span class="nu0">1</span>&lt;ForReady<span class="sy1">.</span>DFolder&gt;<span class="sy1">::</span>get_Count<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">569</span> &nbsp; &nbsp; &nbsp;L_07bc<span class="sy1">:</span>&nbsp; &nbsp; ldc<span class="sy1">.</span>i4<span class="sy1">.</span>0&nbsp; &nbsp; 
<span class="nu0">570</span> &nbsp; &nbsp; &nbsp;L_07bd<span class="sy1">:</span>&nbsp; &nbsp; ble<span class="sy1">.</span>s &nbsp; <span class="nu0">599</span> <span class="sy1">-</span>&gt; ldarg<span class="sy1">.</span>0 
<span class="nu0">571</span> &nbsp; &nbsp; &nbsp;L_07bf<span class="sy1">:</span>&nbsp; &nbsp; ldarg<span class="sy1">.</span>0 
<span class="nu0">572</span> &nbsp; &nbsp; &nbsp;L_07c0<span class="sy1">:</span>&nbsp; &nbsp; ldfld &nbsp; ForReady<span class="sy1">.</span>DFolders ForReady<span class="sy1">.</span>frmMain<span class="sy1">::</span>folds
<span class="nu0">573</span> &nbsp; &nbsp; &nbsp;L_07c5<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>Collections<span class="sy1">.</span>Generic<span class="sy1">.</span>List`<span class="nu0">1</span><span class="sy1">/</span>Enumerator&lt;!<span class="nu0">0</span>&gt; System<span class="sy1">.</span>Collections<span class="sy1">.</span>Generic<span class="sy1">.</span>List`<span class="nu0">1</span>&lt;ForReady<span class="sy1">.</span>DFolder&gt;<span class="sy1">::</span>GetEnumerator<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">574</span> &nbsp; &nbsp; &nbsp;L_07ca<span class="sy1">:</span>&nbsp; &nbsp; stloc<span class="sy1">.</span>s V_30
<span class="nu0">575</span> &nbsp; &nbsp; &nbsp;L_07cc<span class="sy1">:</span>&nbsp; &nbsp; br<span class="sy1">.</span>s&nbsp; &nbsp; <span class="nu0">587</span> <span class="sy1">-</span>&gt; ldloca<span class="sy1">.</span>s V_30
<span class="nu0">576</span> &nbsp; &nbsp; &nbsp;L_07ce<span class="sy1">:</span>&nbsp; &nbsp; ldloca<span class="sy1">.</span>s&nbsp; &nbsp; V_30
<span class="nu0">577</span> &nbsp; &nbsp; &nbsp;L_07d0<span class="sy1">:</span>&nbsp; &nbsp; <span class="kw1">call</span>&nbsp; &nbsp; !<span class="nu0">0</span> System<span class="sy1">.</span>Collections<span class="sy1">.</span>Generic<span class="sy1">.</span>List`<span class="nu0">1</span><span class="sy1">/</span>Enumerator&lt;ForReady<span class="sy1">.</span>DFolder&gt;<span class="sy1">::</span>get_Current<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">578</span> &nbsp; &nbsp; &nbsp;L_07d5<span class="sy1">:</span>&nbsp; &nbsp; stloc<span class="sy1">.</span>s V_5
<span class="nu0">579</span> &nbsp; &nbsp; &nbsp;L_07d7<span class="sy1">:</span>&nbsp; &nbsp; ldarg<span class="sy1">.</span>0 
<span class="nu0">580</span> &nbsp; &nbsp; &nbsp;L_07d8<span class="sy1">:</span>&nbsp; &nbsp; ldfld &nbsp; System<span class="sy1">.</span>Windows<span class="sy1">.</span>Forms<span class="sy1">.</span>ComboBox ForReady<span class="sy1">.</span>frmMain<span class="sy1">::</span>cbxFolders
<span class="nu0">581</span> &nbsp; &nbsp; &nbsp;L_07dd<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>Windows<span class="sy1">.</span>Forms<span class="sy1">.</span>ComboBox<span class="sy1">/</span>ObjectCollection System<span class="sy1">.</span>Windows<span class="sy1">.</span>Forms<span class="sy1">.</span>ComboBox<span class="sy1">::</span>get_Items<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">582</span> &nbsp; &nbsp; &nbsp;L_07e2<span class="sy1">:</span>&nbsp; &nbsp; ldloc<span class="sy1">.</span>s V_5
<span class="nu0">583</span> &nbsp; &nbsp; &nbsp;L_07e4<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>String ForReady<span class="sy1">.</span>DFolder<span class="sy1">::</span>get_Name<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">584</span> &nbsp; &nbsp; &nbsp;L_07e9<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>String System<span class="sy1">.</span>Object<span class="sy1">::</span>ToString<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">585</span> &nbsp; &nbsp; &nbsp;L_07ee<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>Int32 System<span class="sy1">.</span>Windows<span class="sy1">.</span>Forms<span class="sy1">.</span>ComboBox<span class="sy1">/</span>ObjectCollection<span class="sy1">::</span><span class="kw1">Add</span><span class="br0">&#40;</span>System<span class="sy1">.</span>Object<span class="br0">&#41;</span>
<span class="nu0">586</span> &nbsp; &nbsp; &nbsp;L_07f3<span class="sy1">:</span>&nbsp; &nbsp; <span class="kw1">pop</span> 
<span class="nu0">587</span> &nbsp; &nbsp; &nbsp;L_07f4<span class="sy1">:</span>&nbsp; &nbsp; ldloca<span class="sy1">.</span>s&nbsp; &nbsp; V_30
<span class="nu0">588</span> &nbsp; &nbsp; &nbsp;L_07f6<span class="sy1">:</span>&nbsp; &nbsp; <span class="kw1">call</span>&nbsp; &nbsp; System<span class="sy1">.</span>Boolean System<span class="sy1">.</span>Collections<span class="sy1">.</span>Generic<span class="sy1">.</span>List`<span class="nu0">1</span><span class="sy1">/</span>Enumerator&lt;ForReady<span class="sy1">.</span>DFolder&gt;<span class="sy1">::</span>MoveNext<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">589</span> &nbsp; &nbsp; &nbsp;L_07fb<span class="sy1">:</span>&nbsp; &nbsp; brtrue<span class="sy1">.</span>s&nbsp; &nbsp; <span class="nu0">576</span> <span class="sy1">-</span>&gt; ldloca<span class="sy1">.</span>s V_30
<span class="nu0">590</span> &nbsp; &nbsp; &nbsp;L_07fd<span class="sy1">:</span>&nbsp; &nbsp; <span class="kw1">leave</span><span class="sy1">.</span>s <span class="nu0">595</span> <span class="sy1">-</span>&gt; ldarg<span class="sy1">.</span>0 
<span class="nu0">591</span> &nbsp; &nbsp; &nbsp;L_07ff<span class="sy1">:</span>&nbsp; &nbsp; ldloca<span class="sy1">.</span>s&nbsp; &nbsp; V_30
<span class="nu0">592</span> &nbsp; &nbsp; &nbsp;L_0801<span class="sy1">:</span>&nbsp; &nbsp; constrained<span class="sy1">.</span>&nbsp; &nbsp; System<span class="sy1">.</span>Collections<span class="sy1">.</span>Generic<span class="sy1">.</span>List`<span class="nu0">1</span><span class="sy1">/</span>Enumerator&lt;ForReady<span class="sy1">.</span>DFolder&gt;
<span class="nu0">593</span> &nbsp; &nbsp; &nbsp;L_0807<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>Void System<span class="sy1">.</span>IDisposable<span class="sy1">::</span>Dispose<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">594</span> &nbsp; &nbsp; &nbsp;L_080c<span class="sy1">:</span>&nbsp; &nbsp; endfinally&nbsp; 
<span class="nu0">595</span> &nbsp; &nbsp; &nbsp;L_080d<span class="sy1">:</span>&nbsp; &nbsp; ldarg<span class="sy1">.</span>0 
<span class="nu0">596</span> &nbsp; &nbsp; &nbsp;L_080e<span class="sy1">:</span>&nbsp; &nbsp; ldfld &nbsp; System<span class="sy1">.</span>Windows<span class="sy1">.</span>Forms<span class="sy1">.</span>ComboBox ForReady<span class="sy1">.</span>frmMain<span class="sy1">::</span>cbxFolders
<span class="nu0">597</span> &nbsp; &nbsp; &nbsp;L_0813<span class="sy1">:</span>&nbsp; &nbsp; ldc<span class="sy1">.</span>i4<span class="sy1">.</span>0&nbsp; &nbsp; 
<span class="nu0">598</span> &nbsp; &nbsp; &nbsp;L_0814<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>Void System<span class="sy1">.</span>Windows<span class="sy1">.</span>Forms<span class="sy1">.</span>ListControl<span class="sy1">::</span>set_SelectedIndex<span class="br0">&#40;</span>System<span class="sy1">.</span>Int32<span class="br0">&#41;</span>
<span class="nu0">599</span> &nbsp; &nbsp; &nbsp;L_0819<span class="sy1">:</span>&nbsp; &nbsp; ldarg<span class="sy1">.</span>0 
<span class="nu0">600</span> &nbsp; &nbsp; &nbsp;L_081a<span class="sy1">:</span>&nbsp; &nbsp; <span class="kw1">call</span>&nbsp; &nbsp; System<span class="sy1">.</span>Void ForReady<span class="sy1">.</span>frmMain<span class="sy1">::</span>ReadDemands<span class="br0">&#40;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Разберем код поподробнее. Строки<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="79369065"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="79369065" style="height: 126px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
</pre></td><td class="de1"><pre class="de1"><span class="nu0">564</span> &nbsp; &nbsp; &nbsp;L_07ab<span class="sy1">:</span> &nbsp; &nbsp;ldarg<span class="sy1">.</span>0 
<span class="nu0">565</span> &nbsp; &nbsp; &nbsp;L_07ac<span class="sy1">:</span> &nbsp; &nbsp;<span class="kw1">call</span> &nbsp; &nbsp;System<span class="sy1">.</span>Void ForReady<span class="sy1">.</span>frmMain<span class="sy1">::</span>DeserilizeFromCass<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">566</span> &nbsp; &nbsp; &nbsp;L_07b1<span class="sy1">:</span> &nbsp; &nbsp;ldarg<span class="sy1">.</span>0 
<span class="nu0">567</span> &nbsp; &nbsp; &nbsp;L_07b2<span class="sy1">:</span> &nbsp; &nbsp;ldfld &nbsp; ForReady<span class="sy1">.</span>DFolders ForReady<span class="sy1">.</span>frmMain<span class="sy1">::</span>folds
<span class="nu0">568</span> &nbsp; &nbsp; &nbsp;L_07b7<span class="sy1">:</span> &nbsp; &nbsp;callvirt &nbsp; &nbsp;System<span class="sy1">.</span>Int32 System<span class="sy1">.</span>Collections<span class="sy1">.</span>Generic<span class="sy1">.</span>List`<span class="nu0">1</span>&lt;ForReady<span class="sy1">.</span>DFolder&gt;<span class="sy1">::</span>get_Count<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">569</span> &nbsp; &nbsp; &nbsp;L_07bc<span class="sy1">:</span> &nbsp; &nbsp;ldc<span class="sy1">.</span>i4<span class="sy1">.</span>0</pre></td></tr></table></div></td></tr></tbody></table></div>ясны: <code class="inlinecode">get_Count()</code> - получаем folds.Count. <code class="inlinecode">ldc.i4.0</code> - загружаем в стек ноль. Далее<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="418710700"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="418710700" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="nu0">570</span> &nbsp; &nbsp; &nbsp;L_07bd<span class="sy1">:</span>&nbsp; &nbsp; ble<span class="sy1">.</span>s &nbsp; <span class="nu0">599</span> <span class="sy1">-</span>&gt; ldarg<span class="sy1">.</span>0</pre></td></tr></table></div></td></tr></tbody></table></div>это сравнение (условие if(folds.Count &gt; 0), то выполняем код дальше. Иначе переход на инструкцию L_0819).<br />
Далее применяем <code class="inlinecode">GetEnumerator </code>к folds:<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="145389598"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="145389598" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1"><span class="nu0">571</span> &nbsp; &nbsp; &nbsp;L_07bf<span class="sy1">:</span>&nbsp; &nbsp; ldarg<span class="sy1">.</span>0 
<span class="nu0">572</span> &nbsp; &nbsp; &nbsp;L_07c0<span class="sy1">:</span>&nbsp; &nbsp; ldfld &nbsp; ForReady<span class="sy1">.</span>DFolders ForReady<span class="sy1">.</span>frmMain<span class="sy1">::</span>folds
<span class="nu0">573</span> &nbsp; &nbsp; &nbsp;L_07c5<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>Collections<span class="sy1">.</span>Generic<span class="sy1">.</span>List`<span class="nu0">1</span><span class="sy1">/</span>Enumerator&lt;!<span class="nu0">0</span>&gt; System<span class="sy1">.</span>Collections<span class="sy1">.</span>Generic<span class="sy1">.</span>List`<span class="nu0">1</span>&lt;ForReady<span class="sy1">.</span>DFolder&gt;<span class="sy1">::</span>GetEnumerator<span class="br0">&#40;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Сохраняем Enumerator в локальную переменную с условным именем <code class="inlinecode">V_30</code>. И далее снова идет инструкция br.s:<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="327457983"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="327457983" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="nu0">575</span> &nbsp; &nbsp; &nbsp;L_07cc<span class="sy1">:</span>&nbsp; &nbsp; br<span class="sy1">.</span>s&nbsp; &nbsp; <span class="nu0">587</span> <span class="sy1">-</span>&gt; ldloca<span class="sy1">.</span>s V_30</pre></td></tr></table></div></td></tr></tbody></table></div>Согласно мсдн она <code class="inlinecode">выполняет переход к конечной инструкции с указанным смещением</code>. Вот в этой строке и начинается цикл. Переброс происходит на инструкцию 587 (L_07f4). Эта инструкция загружает Enumerator, чтобы применить к нему <code class="inlinecode">MoveNext()</code>. Следующая за тем инструкция brtrue.s:<br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">Передает управление конечной инструкции (короткая форма), если value является true, не равно null или ненулевое значение.</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>То есть если MoveNext вернет true, то переход на инструкцию 576. В самом цикле не происходит ничего особенного: <br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="830760025"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="830760025" style="height: 206px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="de1"><pre class="de1"><span class="nu0">576</span> &nbsp; &nbsp; &nbsp;L_07ce<span class="sy1">:</span>&nbsp; &nbsp; ldloca<span class="sy1">.</span>s&nbsp; &nbsp; V_30
<span class="nu0">577</span> &nbsp; &nbsp; &nbsp;L_07d0<span class="sy1">:</span>&nbsp; &nbsp; <span class="kw1">call</span>&nbsp; &nbsp; !<span class="nu0">0</span> System<span class="sy1">.</span>Collections<span class="sy1">.</span>Generic<span class="sy1">.</span>List`<span class="nu0">1</span><span class="sy1">/</span>Enumerator&lt;ForReady<span class="sy1">.</span>DFolder&gt;<span class="sy1">::</span>get_Current<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">578</span> &nbsp; &nbsp; &nbsp;L_07d5<span class="sy1">:</span>&nbsp; &nbsp; stloc<span class="sy1">.</span>s V_5
<span class="nu0">579</span> &nbsp; &nbsp; &nbsp;L_07d7<span class="sy1">:</span>&nbsp; &nbsp; ldarg<span class="sy1">.</span>0 
<span class="nu0">580</span> &nbsp; &nbsp; &nbsp;L_07d8<span class="sy1">:</span>&nbsp; &nbsp; ldfld &nbsp; System<span class="sy1">.</span>Windows<span class="sy1">.</span>Forms<span class="sy1">.</span>ComboBox ForReady<span class="sy1">.</span>frmMain<span class="sy1">::</span>cbxFolders
<span class="nu0">581</span> &nbsp; &nbsp; &nbsp;L_07dd<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>Windows<span class="sy1">.</span>Forms<span class="sy1">.</span>ComboBox<span class="sy1">/</span>ObjectCollection System<span class="sy1">.</span>Windows<span class="sy1">.</span>Forms<span class="sy1">.</span>ComboBox<span class="sy1">::</span>get_Items<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">582</span> &nbsp; &nbsp; &nbsp;L_07e2<span class="sy1">:</span>&nbsp; &nbsp; ldloc<span class="sy1">.</span>s V_5
<span class="nu0">583</span> &nbsp; &nbsp; &nbsp;L_07e4<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>String ForReady<span class="sy1">.</span>DFolder<span class="sy1">::</span>get_Name<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">584</span> &nbsp; &nbsp; &nbsp;L_07e9<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>String System<span class="sy1">.</span>Object<span class="sy1">::</span>ToString<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">585</span> &nbsp; &nbsp; &nbsp;L_07ee<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>Int32 System<span class="sy1">.</span>Windows<span class="sy1">.</span>Forms<span class="sy1">.</span>ComboBox<span class="sy1">/</span>ObjectCollection<span class="sy1">::</span><span class="kw1">Add</span><span class="br0">&#40;</span>System<span class="sy1">.</span>Object<span class="br0">&#41;</span>
<span class="nu0">586</span> &nbsp; &nbsp; &nbsp;L_07f3<span class="sy1">:</span>&nbsp; &nbsp; <span class="kw1">pop</span></pre></td></tr></table></div></td></tr></tbody></table></div>Никаких скачков, переходов. Исключительно работа со стеком и вызовы лок функций<br />
Но вот если MoveNext вернет 0, то управление перейдет к инструкции leave.s, бросающей нас на № 595<br />
<br />
И если у вас уже терпение на исходе и вы не понимаете, что особенного в этом разборе, то хочу вас обрадовать. Мы дошли до той самой точки, которой я хотел поделиться. Это строки:<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="896773443"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="896773443" style="height: 94px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
</pre></td><td class="de1"><pre class="de1"><span class="nu0">591</span> &nbsp; &nbsp; &nbsp;L_07ff<span class="sy1">:</span>&nbsp; &nbsp; ldloca<span class="sy1">.</span>s&nbsp; &nbsp; V_30
<span class="nu0">592</span> &nbsp; &nbsp; &nbsp;L_0801<span class="sy1">:</span>&nbsp; &nbsp; constrained<span class="sy1">.</span>&nbsp; &nbsp; System<span class="sy1">.</span>Collections<span class="sy1">.</span>Generic<span class="sy1">.</span>List`<span class="nu0">1</span><span class="sy1">/</span>Enumerator&lt;ForReady<span class="sy1">.</span>DFolder&gt;
<span class="nu0">593</span> &nbsp; &nbsp; &nbsp;L_0807<span class="sy1">:</span>&nbsp; &nbsp; callvirt&nbsp; &nbsp; System<span class="sy1">.</span>Void System<span class="sy1">.</span>IDisposable<span class="sy1">::</span>Dispose<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="nu0">594</span> &nbsp; &nbsp; &nbsp;L_080c<span class="sy1">:</span>&nbsp; &nbsp; endfinally</pre></td></tr></table></div></td></tr></tbody></table></div>На них не происходит переход. Они пропускаются в любом случае: и при выполнении цикла и при его завершении<br />
<br />
Что же в них происходит?<br />
<br />
Метод <font color="Blue">constrained </font>ограничивает тип, для которого был вызван виртуальный метод, а Dispose() освобождает ресурсы. Опкод endfinally - это <code class="inlinecode">End finally clause of an exception block</code>.	Что за ерунда? Не ерунда<br />
<br />
Оказывается, к каждому блоку foreach cil-компилятор добавляет автоматически <font color="blue">try</font>-блок. В частности для приведенного выше отрывка к методу был сформирован .try1:<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="637071504"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="637071504" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy1">.</span>try1&nbsp; <span class="nu0">575</span> to <span class="nu0">591</span>&nbsp; Finally handler &nbsp;<span class="nu0">591</span> to <span class="nu0">595</span></pre></td></tr></table></div></td></tr></tbody></table></div>Для циклов <font color="blue">for</font> такого нет. Любопытно, да?<br />
<br />
<b>10. Получение свойств родительских (реализованных) интерфейсов</b><br />
<br />
Об этом уже много написано и кому надо, тот знает. Но на всякий случай напишу<br />
<br />
Мы все знаем метод GetProperties(). У класса он позволяет получить все public свойства static и instance характера (соответствует BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public параметрам). При чем у класса вернет все свойства, в т.ч. и наследуемые. Чтобы это не произошло, надо вызвать с параметром DeclaredOnly. У интерфейсов получить свойства родительского интерфейса нельзя. Например: <br />
<div class="codeblock"><table class="csharp"><thead><tr><td colspan="2" id="123003000"  class="head">C#</td></tr></thead><tbody><tr class="li1"><td><div id="123003000" style="height: 174px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; <span class="kw4">interface</span> A <span class="sy0">:</span> B
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> d <span class="br0">&#123;</span> <span class="kw1">get</span><span class="sy0">;</span> <span class="kw1">set</span><span class="sy0">;</span> <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw4">interface</span> B
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> c <span class="br0">&#123;</span> <span class="kw1">get</span><span class="sy0">;</span> <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Здесь <code class="inlinecode">typeof(A).GetInterfaces()</code> вернет только d<br />
Для того, чтобы получить все свойства, используют такой подход:<br />
<div class="codeblock"><table class="csharp"><thead><tr><td colspan="2" id="727104648"  class="head">C#</td></tr></thead><tbody><tr class="li1"><td><div id="727104648" style="height: 206px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw1">static</span> PropertyInfo<span class="br0">&#91;</span><span class="br0">&#93;</span> GetNonPublicProperties<span class="br0">&#40;</span>Type type<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">var</span> types <span class="sy0">=</span> type<span class="sy0">.</span><span class="me1">GetInterfaces</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List<span class="sy0">&lt;</span>PropertyInfo<span class="sy0">&gt;</span> pr <span class="sy0">=</span> <span class="kw3">new</span> List<span class="sy0">&lt;</span>PropertyInfo<span class="sy0">&gt;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="kw1">var</span> typ <span class="kw1">in</span> types<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pr<span class="sy0">.</span><span class="me1">AddRange</span><span class="br0">&#40;</span>typ<span class="sy0">.</span><span class="me1">GetProperties</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pr<span class="sy0">.</span><span class="me1">AddRange</span><span class="br0">&#40;</span>type<span class="sy0">.</span><span class="me1">GetProperties</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> pr<span class="sy0">.</span><span class="me1">ToArray</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Так же стоит отметить, что, если интерфейс является оболочкой для COM-объекта, то получить свойства, которые не использованы в проекте, не выйдет, поскольку проект не содержит ссылок на них</div>

]]></content:encoded>
			<dc:creator>netBool</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/125422/5250.html</guid>
		</item>
		<item>
			<title>Построение UML-диаграмм для python (plantUML)</title>
			<link>https://www.cyberforum.ru/blogs/125422/5229.html</link>
			<pubDate>Wed, 18 Apr 2018 08:25:45 GMT</pubDate>
			<description>В один прекрасный день в моем проекте Django стало очень много моделей, связанных очень сложно. И я...</description>
			<content:encoded><![CDATA[<div>В один прекрасный день в моем проекте Django стало очень много моделей, связанных очень сложно. И я начал нуждаться в инструменте для построения блок-схем. <br />
Разработкой я занимаюсь в pycharm community без встроенного uml-редактора и только ради него покупать за 12к официал не готов, как и пользоваться им крякнутым в силу моих программистских принципов<br />
<br />
Итак, я приступил к поиску бесплатных UML-редакторов. Мне попался <a rel="nofollow noopener noreferrer" href="http://ru.vlab.wikia.com/wiki/%D0%98%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B_UML-%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_(%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA)" target="_blank" title="http://ru.vlab.wikia.com/wiki/%D0%98%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B_UML-%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_(%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA)">этот </a> список и я стал штудировать их сначала выборочно, потом - все подряд. Впечатления следующие:<ul><li><b>Dia </b>оказалась понятной, но для меня слишком неудобной</li>
<li><b>StarUML </b>намного удобнее, но много жрущей и тормозящей (наверное, на java написана)</li>
<li><b>ArgoUML </b>- по удобству недалеко ушла от Dia, но еще и интерфейс из 90х</li>
<li>Некоторые инструменты, такие, как <b>Gaphor</b>, у меня вообще ставиться отказались, т.к. не смогли скачать python 2.5. (несмотря на то, что у меня стоял 2.7, добавленный во все глобальные переменные, установщик все-таки усиленно пытался скачать именно 2.5 и при каждой неудаче отчаивался и выдавал неисправимую ошибку установки)</li>
<li>Наткнулся на инфу, что в <b>phpmyadmin </b>есть подобный инструмент. Даже не пробуйте - фигня полная</li>
</ul><br />
Попалась мне интересная программка <b>NClass</b>. Мне там понравилось все, за исключением того, что она под C#. Я, конечно, люблю шарп (и взял ее на заметку), но каждый раз нужно писать вручную тип поля, что не оч удобно, а моем случае и не очень нужно. Зато генерирует исходный код, что довольно приятно. (кстати, не нашел там вид связи - наследование)<br />
<br />
Пробовал так же и встроенный  в <b>VS </b>визуалайзер EDM-диаграмм. Прикольная штука, подобна NClass, но тоже много лишнего + там все завязано на генерацию кода. Это настоящий самолет со всеми вытекающими возможностями и ...заморочками. А заморочки как раз-таки мне не нужны...<br />
<br />
В общем эти приключения можно описывать долго и заняли они у меня почти весь день... <br />
<br />
Вотс. Но тк я использую pycharm, решил остановиться на решениях для pycharm. Я как-то и не вспоминал до этого момента, что эта ide поддерживает плагины. Выбор, конечно, не велик... но это как раз то, на чем я остановился<br />
Плагин называется <b>plantUML</b> integration. Далее я расскажу подробно этапы установки и настройки, т.к. на мой взгляд, не все из них являются интуитивно понятными: <br />
Сначала все просто: идем в File-&gt;Settings-&gt;Plagins. Вбиваем в строку поиска plantUML, устанавливаем, перезагружаем ide. И видим, что справа появилась вкладка plantUML<br />
<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=4757&amp;d=1524038918" rel="Lightbox" id="attachment4757" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=4757&amp;thumb=1&amp;d=1524038918" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: Безымянный.png
Просмотров: 2224
Размер:	237.2 Кб
ID:	4757" style="margin: 5px" /></a><br />
<br />
Ок. Но этого мало. Нужно установить скачать и установить Graphviz под вашу операционную систему, иначе будет ругаться<br />
У меня была Windows... Но и этого мало. В настройках вкладки plantUML (там всего три пункта: Delay, Cache Size и Graphviz dot executable) в последнем пункте нужно указать путь к dot.exe из каталога Graphviz/bin/<br />
У меня это <br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">E:/ProgramFiles/Graphviz2.38/bin/dot.exe</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Собственно, можно приступать к построению диаграмм. Для построения диаграмм в plantUML используется специальный язык разметки DOT. <br />
<div class="codeblock"><table class="css"><thead><tr><td colspan="2" id="306651030"  class="head">CSS</td></tr></thead><tbody><tr class="li1"><td><div id="306651030" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1">@startuml
&nbsp;
Profile <span class="re4">--</span> Class10
&nbsp;
@enduml</pre></td></tr></table></div></td></tr></tbody></table></div> Это не сложно и для меня легче описать что-то на языке дот, чем тыкаться в визуальном редакторе ArgoUML. В сети я нашел подробную <a rel="nofollow noopener noreferrer" href="http://plantuml.com/class-diagram" target="_blank" title="http://plantuml.com/class-diagram">инструкцию</a> на русском (чего сам не ожидал!) языке. <br />
Пожалуй все, <br />
А, ну да. plantuml не умеет строить диаграммы по исходному коду, в ч-сти по и/к Джанго. Но собственно для меня это и не было обязательно<br />
<br />
Так же предлагаю полезные ссылки по теме:<ul><li><a rel="nofollow noopener noreferrer" href="https://en.wikipedia.org/wiki/List_of_Unified_Modeling_Language_tools" target="_blank" title="https://en.wikipedia.org/wiki/List_of_Unified_Modeling_Language_tools">Вики</a></li>
<li><a rel="nofollow noopener noreferrer" href="https://habrahabr.ru/post/46648/" target="_blank" title="https://habrahabr.ru/post/46648/">Обзор UML-редакторов на хабре</a></li>
<li><a rel="nofollow noopener noreferrer" href="http://www.uml2.ru/forum/index.php?topic=1091.0" target="_blank" title="http://www.uml2.ru/forum/index.php?topic=1091.0">Обзор UML-редакторов в ветке uml2.ru</a></li>
</ul><br />
PS: Для переноса полей с джанго накидал простенькую регулярку<br />
<br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message"> \= [^\n]+</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>По ней в np++ удаляю matches, остаются только названия полей. Остается только paste в dot-код</div>

]]></content:encoded>
			<dc:creator>netBool</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/125422/5229.html</guid>
		</item>
		<item>
			<title>Преобразование структуры в массив байт</title>
			<link>https://www.cyberforum.ru/blogs/125422/5211.html</link>
			<pubDate>Fri, 06 Apr 2018 13:38:37 GMT</pubDate>
			<description><![CDATA[Уже полтора дня потерял в поисках ответа, почему не работает вот этот код:  
 
	  BYTE arr[6]; 
	 ...]]></description>
			<content:encoded><![CDATA[<div>Уже полтора дня потерял в поисках ответа, почему не работает вот этот код: <br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="641757538"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="641757538" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; &nbsp; BYTE arr<span class="br0">&#91;</span><span class="nu0">6</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; BYTE<span class="sy2">*</span> _arr <span class="sy1">=</span> arr<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; <span class="sy2">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>jmp_far<span class="sy2">*</span><span class="br0">&#41;</span>_arr<span class="br0">&#41;</span> <span class="sy1">=</span> jump<span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>где jump - это jmp_far, а BYTE - unsigned char<br />
<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="210344494"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="210344494" style="height: 126px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
</pre></td><td class="de1"><pre class="de1"><span class="kw4">struct</span> jmp_far
<span class="br0">&#123;</span>
&nbsp; BYTE instr_push<span class="sy4">;</span> &nbsp;<span class="co1">//здесь будет код инструкции push</span>
&nbsp; DWORD arg<span class="sy4">;</span> &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//аргумент push</span>
&nbsp; BYTE &nbsp;instr_ret<span class="sy4">;</span> &nbsp; &nbsp;<span class="co1">//здесь будет код инструкции ret</span>
<span class="br0">&#125;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Изначально jump заполнен данными, которые хорошо видны в отладчике, но после присвоения указателя разыменнованному указателю на массив байт, все рушится. Фактически передается только 1й байт (среда VS2010) <br />
<br />
Оказывается, есть такая маленькая настроечка: <br />
Проект-&gt;Свойства-&gt;Свойства конфигурации-&gt;C++-&gt;Создание кода-&gt;Выравнивание членов структур-&gt;1 байт (\Zp1). <br />
<b>И все, вуаля! Все заработало!!</b><br />
но блин, ребята, полтора дня! <br />
<br />
До этого стояло &quot;по умолчанию&quot;... так вот по умолчанию, видимо, 4 байта...<br />
<br />
<b>PS</b>: как верно подметил в комментариях Rius, что можно было это сделать и с помощью #pragma (работает для MinGW и GCC). Под QTCreator (где нет настроек с \Zp1) я сделал так: <br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="72010494"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="72010494" style="height: 126px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
</pre></td><td class="de1"><pre class="de1"><span class="co2">#pragma pack(1)</span>
<span class="kw4">struct</span> jmp_far
<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp;<span class="co1">//поля</span>
<span class="br0">&#125;</span><span class="sy4">;</span>
<span class="co2">#pragma pack()</span></pre></td></tr></table></div></td></tr></tbody></table></div><b>PPS</b>: На linux.org встретил мнение, что выравнивание по 1 байту увеличивает время доступа к полям структуры. Не проверял, в моем случае скорость не имела сильного значения.<br />
<br />
Но можно, конечно, и без выравнивания сделать. <br />
Думаю, на нашем примере будет наиболее оптимально так:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="342360591"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="342360591" style="height: 94px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; BYTE ch<span class="br0">&#91;</span><span class="nu0">6</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="sy2">*</span>ch <span class="sy1">=</span> jump.<span class="me1">instr_push</span><span class="sy4">;</span> &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; <span class="sy2">*</span><span class="br0">&#40;</span>DWORD<span class="sy2">*</span><span class="br0">&#41;</span><span class="br0">&#40;</span>ch<span class="sy2">+</span><span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy1">=</span> jump.<span class="me1">arg</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="sy2">*</span><span class="br0">&#40;</span>ch<span class="sy2">+</span><span class="nu0">5</span><span class="br0">&#41;</span><span class="sy1">=</span>jump.<span class="me1">instr_ret</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div></div>

]]></content:encoded>
			<dc:creator>netBool</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/125422/5211.html</guid>
		</item>
		<item>
			<title>Полиморфизм в моделях джанго</title>
			<link>https://www.cyberforum.ru/blogs/125422/5203.html</link>
			<pubDate>Fri, 30 Mar 2018 14:46:27 GMT</pubDate>
			<description>Маленькая запись-напоминалочка, что в джанго можно использовать полиморфизм в том числе и в полях...</description>
			<content:encoded><![CDATA[<div>Маленькая запись-напоминалочка, что в джанго можно использовать полиморфизм в том числе и в полях модели. <br />
Для этого можно использовать ContentType для реализации абсолютно обобщенных (иногда говорят “полиморфных”) отношений между моделями.<br />
Классический джанго-полиморфизм на уровне модели выглядит это примерно так:<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="212427171"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="212427171" style="height: 142px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
</pre></td><td class="de1"><pre class="de1"><span class="kw1">from</span> django.<span class="me1">contrib</span>.<span class="me1">contenttypes</span>.<span class="me1">fields</span> <span class="kw1">import</span> GenericForeignKey
<span class="kw1">from</span> django.<span class="me1">contrib</span>.<span class="me1">contenttypes</span>.<span class="me1">models</span> <span class="kw1">import</span> ContentType
&nbsp;
<span class="kw1">class</span> Note<span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>: <span class="co1">#Note</span>
&nbsp; &nbsp; Target_Type <span class="sy0">=</span> models.<span class="me1">ForeignKey</span><span class="br0">&#40;</span>ContentType<span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; TargetId <span class="sy0">=</span> models.<span class="me1">PositiveIntegerField</span><span class="br0">&#40;</span><span class="br0">&#41;</span> &nbsp; &nbsp;
&nbsp; &nbsp; ToTarget <span class="sy0">=</span> GenericForeignKey<span class="br0">&#40;</span><span class="st0">'Target_Type'</span><span class="sy0">,</span> <span class="st0">'TargetId'</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Как это реализовать? <br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">Существуют три правила по созданию и настройке GenericForeignKey:<br />
<br />
Создайте в вашей модели поле типа ForeignKey, указав в качестве внешней модели ContentType. Обычно такому полю дают имя “content_type”.<br />
<br />
Создайте в вашей модели поле, которое будет хранить значения первичных ключей экземпляров модели, с которой вы создаете связь. Для большинства моделей, это поле типа PositiveIntegerField. Обычно такому полю дают имя “object_id”.<br />
<br />
Создайте в вашей модели поле типа GenericForeignKey, и передайте ему в качестве аргументов, имена полей созданных ранее. Если эти поля названы “content_type” и “object_id”, вы можете не передавать их, – эти имена используются в GenericForeignKey по умолчанию.</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Это перевод оф. документации от джбук.ру<br />
<br />
В том же переводе сказано, что в 1.9 уберут эту возможность. Но в django 1.11 она по прежнему есть:p<br />
<br />
Итак, после создания связи мы можем использовать API, похожий на тот, что используется в обычном ForeignKey; каждый Note содержит поле ToTarget, которое возвращает связанный с ним объект. Мы можем присвоить этому полю произвольный объект, или указать этот объект при создании Note:<br />
<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="836622174"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="836622174" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">Note<span class="br0">&#40;</span>ToTarget<span class="sy0">=</span>User.<span class="me1">objects</span>.<span class="me1">get</span><span class="br0">&#40;</span>username<span class="sy0">=</span><span class="st0">'Mima'</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>(Также GenericForeignKeys не отображется в ModelForms)<br />
<br />
Как многие, наверное, заметили, эта возможность не связана с наследованием, как принято в языках программирования. Но наследование так же есть в джанго. Для этого необходимо объявить абстрактную модель, от которой будем наследоваться, вот так: <br />
<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="608225412"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="608225412" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1"><span class="kw1">class</span> MyBaseModel<span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; <span class="kw1">class</span> Meta:
&nbsp; &nbsp; &nbsp; &nbsp; abstract <span class="sy0">=</span> <span class="kw2">True</span> &nbsp; &nbsp;<span class="co1"># данное поле указывает, что класс абстрактный</span></pre></td></tr></table></div></td></tr></tbody></table></div>И дальше: <br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="329678572"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="329678572" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1"><span class="kw1">class</span> Comment<span class="br0">&#40;</span>PostBase<span class="br0">&#41;</span>:
&nbsp; &nbsp; <span class="kw1">class</span> Meta:
&nbsp; &nbsp; &nbsp; &nbsp; db_table <span class="sy0">=</span> <span class="st0">&quot;comments&quot;</span>
&nbsp;
&nbsp; &nbsp; article <span class="sy0">=</span> models.<span class="me1">ForeignKey</span><span class="br0">&#40;</span>Article<span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Абстрактная модель не создает таблиц.<br />
<br />
Это очень хорошая возможность сократить код. Итак, домашнее задание: можно ли ее использовать так же и для полиморфизма?</div>

]]></content:encoded>
			<dc:creator>netBool</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/125422/5203.html</guid>
		</item>
		<item>
			<title>На чем пишутся сайты?</title>
			<link>https://www.cyberforum.ru/blogs/125422/5194.html</link>
			<pubDate>Sun, 25 Mar 2018 12:26:54 GMT</pubDate>
			<description>Новички часто задают этот вопрос. На чем написан гугл и яндекс? Какой язык или технологию учить,...</description>
			<content:encoded><![CDATA[<div>Новички часто задают этот вопрос. На чем написан гугл и яндекс? Какой язык или технологию учить, чтобы быть востребованным? Или на чем писать стартап, который в случае успеха сможет держать огромные нагрузки?  И что начать учить сейчас, чтобы не влететь в будущем? <br />
<br />
Такие вопросы интересуют каждого неравнодушного обывателя, вставшего перед выбором. Когда-то этот вопрос заинтересовал и меня. В качестве стэка я выбирал между python&amp;Django, ASP.NET и множественными фрэймворками php и, остановившись на джанго, засомневался, а выдержит ли он серьезные нагрузки? Достаточно ли он безопасен? И тогда я решил найти известные высоконагруженные сайты на нем в сети. Первое, на что я наткнулся, была статья на <a rel="nofollow noopener noreferrer" href="https://habrahabr.ru/company/SECL_GROUP/blog/218921/" target="_blank" title="https://habrahabr.ru/company/SECL_GROUP/blog/218921/">хабре</a>. На самом деле это был перевод англоязычной статьи от 2014 года и у меня появилось много сомнений в объективности этих данных. Во-первых, сайты постоянно переписываются. И возможно, некоторые из них действительно начинались на джанго, но где подтверждения, что они там остались и сейчас? Во-вторых, является ли в них джанго основным фреймворком? Или это просто какой-то не основной дополнительный сервис, на который и нагрузки то не приходится? <br />
<br />
И тогда вооружившись wapalyzer-ом и поддержкой builtwith.com :) начал свое собственное исследование бэкэнд-технологий самых популярных, нагруженных и защищенных сайтов в сети.<br />
<br />
Начну, я пожалуй с php. Это действительно самый распространенный язык для веб-разработки. У меня сложилось впечатление, что доля сайтов на php процентов 90. И по началу я хотел вообще опустить его в этом обзоре с оговоркой, что все сайты, которые не попали сюда, написаны на php:D. Фактически сейчас, если кто-то задает вопрос по серверной веб-разработке вне тем форума без упоминания этой технологии, то по дефолту подразумевается именно php. И честно говоря до этого я думал, что php берет количественно, а не качественно и серьезных сайтов (vk и facebook - типа исключения) на нем просто не делают. Но меня ждало разочарование... <br />
<br />
Начну с настоящего форума, где мы постоянно делимся и получаем знания. На данный момент - это пожалуй самый посещаемый в рунете ресурс по программированию (более 150 тыс./ч. в сутки). Так же на php написан и habrahabr. Но еще больше меня поразили <a rel="nofollow noopener noreferrer" href="https://rshb.ru/" target="_blank" title="https://rshb.ru/">росельхозбанк </a>(1с-битрикс) и <a rel="nofollow noopener noreferrer" href="https://Gazprombank.ru" target="_blank" title="https://Gazprombank.ru">газпромбанк </a>(1с-битрикс).<br />
Мало того, что они сделаны на php, но последние еще и на битриксе. Ребята, а ведь это банки! В т.ч. онлайн-банки, где защита от атак должна быть железобетонной. После них я даже не знал, хуже ли относиться к этим банкам или лучше к php/bitrix. Ну да ладно, не буду томить дальше. Вот перечень некоторых сайтов на<br />
<br />
<font size="5"><div align="center">PHP:</div></font><br />
<ul><li>lamoda.ru</li>
<li>citilink.ru</li>
<li>price.ru</li>
<li>DROM.RU</li>
<li>gismeteo.ru</li>
<li>infox.ru - yii - 500тыс ч/сут</li>
<li>ren.tv - drupal - 660тыс ч/сут</li>
<li>svyaznoy.ru - yii(осн)/bitrix</li>
<li>dns-shop.ru - yii</li>
<li>technopoint.ru - yii</li>
<li>superjob.ru - yii</li>
</ul>и много других сайтов на битрикс и yii. На пхп написаны почти все новостные сайты и банки<br />
<br />
Мало? И вы не уверены, что php - действительно серьезный язык, у которого есть будущее?<br />
Значит, я рано остановился:<br />
<ul><li>vk.com (на начало 2018г посещаемость - 30млн чел/сут.)</li>
<li>hitachi.com (есть ли кто, кто не знает имя этой фирмы?)</li>
<li>facebook.com (без комментариев)</li>
<li>yahoo.com (без комментариев)</li>
<li>amazon.com (вообще без комментариев)</li>
<li>MorganStanley.com (один из самых авторитетных финансовых гигантов США)</li>
<li>wordpress.org (блого-сайт от разработчиков самой популярной cms - 500 тыс. посетителей в сутки)</li>
</ul><br />
и много-много других. В общем выводы. Настоящее у php есть точно. На нем написаны одни из самых наруженных сайтов сети, мировые гиганты, такие как амазон, стоимостью миллиарды долларов. Писать на нем точно не стыдно<br />
<br />
Из cms попадались часто drupal. Кстати, ни одного высоконагруженного сайта на joomla и wordpress (кроме wordpress.org - кстати wordpress.org - неплохой показатель)<br />
<br />
Ну что? Имеет ли смысл говорить о чем-то еще, когда есть php? :)<br />
<br />
После всего этого перечня может сложиться впечатление, что серьезные сайты пишутся только на php. Но это в корне не верно :)<br />
<br />
Итак, представлю asp.net. Эта технология, которая меня интересовала больше всего после джанго, тк я неравнодушен к C# с его строгой типизацией и удобными бесплатными инструментами от Microsoft. На нем очень удобно вести большие проекты. При чем все ошибки, если они есть, будут сразу на виду и будут легко исправлены. Кроме того, скорость работы .NET на порядок (если не на 3 порядка) превышают скорость работы любого интерпретируемого языа (в т.ч. php). Итак, начну с builtwith.com. Он, конечно, не может похвастаться нагрузкой (5т/день согласно pr-cy.ru), но зато может неплохим функционалом.<br />
<br />
<font size="5"><div align="center">ASP.NET</div></font><br />
<br />
Сайты рунета: <br />
dnevnik.ru - (сервис онлайн-дневников по всей России от Краснодара до Петербурга) 30тыс ч/день<br />
finanz.ru - (новости финансов - 50тыс ч/сут)<br />
computermarket.ru - интернет-магазин 10тыс/д<br />
ozon.ru (некогда популярный интернет-магазин. Один из первых федеральных в России. Посещаемость сейчас - 40тыс ч/с)<br />
sql.ru (форум о программировании)<br />
domofond.ru - 250тыс ч/сут(!)<br />
Издательский дом &quot;Коммерсант&quot; - 550т/сут!!! (top1000-ru)<br />
nalog.ru (частично, но 455тыс в сут!!)<br />
bcs-express.ru (банк и брокерские услуги)<br />
<br />
Международные:<ul><li>similarweb.com - 65т/д</li>
<li>discovery.com</li>
<li>stackoverflow.com - (согласно alexa - 30 т/сут, не уверен, что соответствует действительности)</li>
<li>microsoft.com - 450 тыс/сут</li>
<li>dell.com</li>
<li>bankofamerica.com 		/частично</li>
<li>bing.com - второй после гугла поисковик в США (посещаемость можете себе представить)</li>
</ul><br />
<br />
<font size="5"><div align="center">JAVA</div></font><br />
<br />
О серьезном вкладе java в EE решения можно судить по этим трем сайтам: ok.ru (на начало 2018г 10 млн ч/сут), sberbank.ru и ali-express.com. Так же на java сделаны сервисы google: analitics и search console<br />
<br />
Так же в этот список можно внести:<br />
<ul><li>discoverychanel.ru</li>
<li>втб //(частично asp?)</li>
<li>intel</li>
<li>сименс</li>
<li>ebay.com</li>
<li>service.nalog.ru</li>
<li>bankofamerica.com 		/частично</li>
<li>тинькофф-банк</li>
</ul><br />
<font size="5"><div align="center">NODE.JS (EXPRESS)</div></font><br />
<ul><li>rambler.ru - express node.js - 2млн/сут</li>
<li>avto.ru - express -//- - 480 т/сут</li>
<li>forbes.com</li>
<li>paypal.com - частично на Express, частично на J2EE, частично на php</li>
<li>IONICFRAMEWORK.COM</li>
</ul><br />
<font size="5"><div align="center">ruby (on rails)</div></font><br />
<ul><li>blizko.ru - 200 т/д</li>
<li>codepen.io !!!</li>
<li>github.com</li>
<li>какой-то банк из топ 100, не помню какой. Но это меня удивило</li>
</ul><br />
<font size="5"><div align="center">lua</div></font><ul><li>56.COM - видеохостинг. Больше 1млн/сут (OpenResty) - не быстр))</li>
<li>serpstat.com</li>
</ul><br />
Ну и наконец: <br />
<br />
<div align="center"><font size="5">Django</font></div><br />
Сперва я совсем расстроился, так как не нашел подтверждению, что сайты из вышеприведенной статьи используют джанго, даже напротив. Напротив, даже были опровержения. Например, discovery - это java/asp стэк. Там нет и признаков python, тем не менее он был в этом списке. В том же списке google.com. Признаков использования джанго в гугл я не нашел. Что самое интересное, я не сомневаюсь, что они его используют, но в каком-нибудь второстепенном сервисе. Аргумент о том, что гугл написан на джанго как минимум высосаны из пальца. Там же theguardian.com. Ребята! Ну после <a rel="nofollow noopener noreferrer" href="https://ru.wikipedia.org/wiki/Scala_(%D1%8F%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)#%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5" target="_blank" title="https://ru.wikipedia.org/wiki/Scala_(%D1%8F%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)#%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5">этого</a> я вообще к подобным спискам доверие потерял:<br />
<br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">В апреле 2011 онлайн-версия газеты The Guardian была переведена с Java на Scala[10].</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Хочется спросить, где там джанго, ребята? И builtwith, на который ссылается автор хабрастатьи, никаких признаков ни джанго ни питона  в Guardian  не нашел<br />
<br />
Постоянно фигурирует ютуб, но подтверждания, что ютуб сейчас использует именно джанго, я не нашел нигде. Вполне вероятно, в процессе развития видеогиганта там от джанго осталось одно название, а все остальное переписано либо на cython либо на jython. Но начнем с малого: djbook.ru (5тыс ч/д - не густо). Затем я случайно наткнулся на Продокторов.ру (100 т - я.метрика информер - уже неплохо! При чем сайт работает довольно сносно). И долго думал, что это такая белая вопрона рунета. Но не... Далее мне попался ГоворитМосква (120 т ч/сут - согласно pr-cy), потом spravker.ru - 152016 тыс ч/день (рамблер) и jsprav.ru и наконец rutube.ru - 60тыс ч/д. <br />
<br />
instagram, который везде приводят, как образец django-продакшна оказался сделан на джанго частично. В pinterest.com  мои плагины определили только язык программирования - python. То же самое я мог сказать и про дискус, но на их сайте наткнулся на <a rel="nofollow noopener noreferrer" href="https://blog.disqus.com/scaling-django-to-8-billion-page-views" target="_blank" title="https://blog.disqus.com/scaling-django-to-8-billion-page-views">блог</a>, в котором вряд ли писали неправду. Никаких опровержений мои плагины не выдали, так что я спокойно зачислил его в свою джанго-коллекцию. Так же мои сомнения по тихоньку растаяли и по поводу pinterest.com. А значит на джанго вполне можно делать высоконагруженные сайты, которые могут выдерживать нагрузки киберфорума и выше :) Ура :)<br />
<br />
Кроме того на джанго написаны:<ul><li>jsfiddle.net</li>
<li>mozilla.org (research - на wordpress(почти не посещается. В месяц 30т/человек), а addons на джанго (полмиллиона посетителей в сутки по спайметрике))</li>
<li>minecraft.net -  (30 тыс ч/сут согласно pr-cy - не уверен, что объективно, по SimilarWeb.com - 600т/мес)</li>
<li>bitbucket.org -  (45тыс/д согласно pr-cy - alexa, тоже не уверен)</li>
<li>yipit.com - 5т/д (примерно) по SimilarWeb.com</li>
<li>disqus.com - в блоге написано о джанго: (pr-cy: 50т/д, SimilarWeb.com: 900т/д)</li>
</ul><br />
Посещаемости некоторых зарубежных сайтов мной могут быть приведены неверно, я сильно не углублялся. Брал статистику в основном с alexa, а она часто приводила довольно странные цифры, не совпадающие с другими счетчиками. Но к сожалению, эти &quot;другие&quot; счетчики не всегда открыты, так что приходилось иметь дело с тем, с чем имел<br />
<br />
Между тем стоит отметить, что посещаемость pinterest на момент написания статьи - более 12 млн поситителей в сутки согласно спайметрикс (вот тебе и питон)<br />
<br />
<div align="center"><font size="5">Какие выводы? Что пожелать на последок? </font></div><br />
Все технологии заслуживают уважения.  Стоит отметить, что Java в основном любят серьезные компании с именем, а на python, например, я не нашел ни одного сайта из банковской сферы. Казалось бы, банкиры не очень доверяют опенсорсным технологиям... Но это не верно, ведь почему-то многие из них доверяют php. <br />
<br />
В общем, считаю, любую технологию можно использовать с умом и довести до совершенства, и тогда она сможет решать любые задачи<br />
<br />
Это был весьма краткий обзор. К сожалению, на бОльший у меня нет времени. Если есть какие-то мысли и предложения, пишите в комментариях. Надеюсь, информация будет полезна</div>

]]></content:encoded>
			<dc:creator>netBool</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/125422/5194.html</guid>
		</item>
		<item>
			<title>Расширенные возможности ManyToMany в Django</title>
			<link>https://www.cyberforum.ru/blogs/125422/5193.html</link>
			<pubDate>Sat, 24 Mar 2018 13:57:28 GMT</pubDate>
			<description>В свое время меня интересовали возможности нестандартные возможности ManyToMany в Джанго с...</description>
			<content:encoded><![CDATA[<div>В свое время меня интересовали возможности нестандартные возможности ManyToMany в Джанго с использованием through (так сказать, промежуточных классов). И в этом обзоре я хочу осветить именно этот вопрос. <br />
<br />
На эту тему я мало нашел информации в сети, особенно русскоязычной. Но есть классный перевод на <a rel="nofollow noopener noreferrer" href="https://habrahabr.ru/post/74967/" target="_blank" title="https://habrahabr.ru/post/74967/">хабре</a>, к сожалению, не очень читабельный из-за неуместного использования тегов:(. Из-за этого чтиво ее превратилось в квест по дешифровке примеров кода из хтмл-абракадабры, и я решил привести его часть в более менее читабельный вид тут.<br />
<br />
<b>Итак</b>. В статье автор предлагает рассмотреть случай, когда приложение отслеживает группы, в которых некоторые музыканты принимали участие.<br />
<br />
Отношение между музыкантом и группами, участником которых он являлся или является, будут вида многие-к-многим, поэтому для его представления вы можете использовать ManyToManyField. Однако так же вас может интересовать большое количество деталей, таких как дата вступления в группу или причина, по которой музыкант ее покинул:<br />
<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="202562337"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="202562337" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="de1"><pre class="de1"><span class="co1">#класс музыкант:</span>
<span class="kw1">class</span> Person<span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp;name <span class="sy0">=</span> models.<span class="me1">CharField</span><span class="br0">&#40;</span>max_length<span class="sy0">=</span><span class="nu0">128</span><span class="br0">&#41;</span>
&nbsp;
&nbsp; &nbsp; &nbsp;<span class="kw1">def</span> <span class="kw4">__unicode__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">name</span>
&nbsp;
<span class="co1">#класс группа:</span>
<span class="kw1">class</span> Group<span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; name <span class="sy0">=</span> models.<span class="me1">CharField</span><span class="br0">&#40;</span>max_length<span class="sy0">=</span><span class="nu0">128</span><span class="br0">&#41;</span>
&nbsp; &nbsp; members <span class="sy0">=</span> models.<span class="me1">ManyToManyField</span><span class="br0">&#40;</span>Person<span class="sy0">,</span> through<span class="sy0">=</span><span class="st0">'Membership'</span><span class="br0">&#41;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__unicode__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">name</span>
&nbsp;
<span class="kw1">class</span> Membership<span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; person <span class="sy0">=</span> models.<span class="me1">ForeignKey</span><span class="br0">&#40;</span>Person<span class="br0">&#41;</span>
&nbsp; &nbsp; group <span class="sy0">=</span> models.<span class="me1">ForeignKey</span><span class="br0">&#40;</span>Group<span class="br0">&#41;</span>
&nbsp; &nbsp; date_joined <span class="sy0">=</span> models.<span class="me1">DateField</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; invite_reason <span class="sy0">=</span> models.<span class="me1">CharField</span><span class="br0">&#40;</span>max_length<span class="sy0">=</span><span class="nu0">64</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>При создании промежуточной модели вы явно указываете внешние ключи для моделей, которые вовлечены в отношение вида многие-к-многим. Это однозначное объявление и определяет способы взаимодействия объектов.<br />
<br />
Существует несколько ограничений, касающихся промежуточных моделей:<ol style="list-style-type: decimal"><li>Ваша промежуточная модель должна содержать один и <b>только один внешний ключ к целевой модели</b> (в нашем примере это Person), иначе будет сгенерирована ошибка проверки (validation error).</li>
<li>Ваша промежуточная модель должна содержать один и <b>только один внешний ключ к исходной модели</b> (в нашем примере это Group), иначе будет сгенерирована ошибка проверки (validation error).</li>
<li>Единственным исключением является модель, которая имеет отношение многие-к-многим сама с собой и ссылается на себя с помощью промежуточной модели. В этом случае разрешается использовать два внешних ключа к одной и той же модели, но они буду рассматриваться как две различные части в отношениях вида многие-к-многим.</li>
<li><b>Для определения модели, которая ссылается сама на себя с помощью промежуточной модели, вы должны использовать symmetrical=False</b> (подробнее в справке по полям моделей).</li>
</ol><br />
Теперь, после того как вы настроили ManyToManyField для взаимодействия с вашей промежуточной моделью, вы можете начать создание нескольких отношений вида многие-к-многим. Делается это путем создания экземпляров вашей промежуточной модели:<br />
<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="46184571"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="46184571" style="height: 174px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
</pre></td><td class="de1"><pre class="de1">ringo <span class="sy0">=</span> Person.<span class="me1">objects</span>.<span class="me1">create</span><span class="br0">&#40;</span>name<span class="sy0">=</span><span class="st0">&quot;Ringo Starr&quot;</span><span class="br0">&#41;</span>
paul <span class="sy0">=</span> Person.<span class="me1">objects</span>.<span class="me1">create</span><span class="br0">&#40;</span>name<span class="sy0">=</span><span class="st0">&quot;Paul McCartney&quot;</span><span class="br0">&#41;</span>
beatles <span class="sy0">=</span> Group.<span class="me1">objects</span>.<span class="me1">create</span><span class="br0">&#40;</span>name<span class="sy0">=</span><span class="st0">&quot;The Beatles&quot;</span><span class="br0">&#41;</span>
m1 <span class="sy0">=</span> Membership<span class="br0">&#40;</span>person<span class="sy0">=</span>ringo<span class="sy0">,</span> 
&nbsp; &nbsp;group<span class="sy0">=</span>beatles<span class="sy0">,</span>
&nbsp; &nbsp;date_joined<span class="sy0">=</span>date<span class="br0">&#40;</span><span class="nu0">1962</span><span class="sy0">,</span> <span class="nu0">8</span><span class="sy0">,</span> <span class="nu0">16</span><span class="br0">&#41;</span><span class="sy0">,</span>
&nbsp; &nbsp;invite_reason<span class="sy0">=</span> <span class="st0">&quot;Needed a new drummer.&quot;</span><span class="br0">&#41;</span>
m1.<span class="me1">save</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="kw1">print</span><span class="br0">&#40;</span>beatles.<span class="me1">members</span>.<span class="kw2">all</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>
<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">[&lt;Person: Ringo Starr&gt;]</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table><div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="400426565"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="400426565" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw1">print</span><span class="br0">&#40;</span>ringo.<span class="me1">group_set</span>.<span class="kw2">all</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>
<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">[&lt;Group: The Beatles&gt;]</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table><div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="572292610"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="572292610" style="height: 94px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
</pre></td><td class="de1"><pre class="de1">m2 <span class="sy0">=</span> Membership.<span class="me1">objects</span>.<span class="me1">create</span><span class="br0">&#40;</span>person<span class="sy0">=</span>paul<span class="sy0">,</span> group<span class="sy0">=</span>beatles<span class="sy0">,</span>
&nbsp; &nbsp; date_joined<span class="sy0">=</span>date<span class="br0">&#40;</span><span class="nu0">1960</span><span class="sy0">,</span> <span class="nu0">8</span><span class="sy0">,</span> <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">,</span>
&nbsp; &nbsp; invite_reason<span class="sy0">=</span> <span class="st0">&quot;Wanted to form a band.&quot;</span><span class="br0">&#41;</span>
<span class="kw1">print</span><span class="br0">&#40;</span>beatles.<span class="me1">members</span>.<span class="kw2">all</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>
<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">[&lt;Person: Ringo Starr&gt;, &lt;Person: Paul McCartney&gt;]</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Не очень похоже на обычные поля: <b>вы не можете использовать методы add и create, а также операцию присваивания (например, beatles.members = [...]) для определения отношений:</b><br />
<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="393920256"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="393920256" style="height: 126px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
</pre></td><td class="de1"><pre class="de1"><span class="co1"># это не будет работать:</span>
beatles.<span class="me1">members</span>.<span class="me1">add</span><span class="br0">&#40;</span>john<span class="br0">&#41;</span>
<span class="co1"># NEITHER WILL THIS</span>
beatles.<span class="me1">members</span>.<span class="me1">create</span><span class="br0">&#40;</span>name<span class="sy0">=</span><span class="st0">&quot;George Harrison&quot;</span><span class="br0">&#41;</span>
<span class="co1"># AND NEITHER WILL THIS</span>
beatles.<span class="me1">members</span> <span class="sy0">=</span> <span class="br0">&#91;</span>john<span class="sy0">,</span> paul<span class="sy0">,</span> ringo<span class="sy0">,</span> george<span class="br0">&#93;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Почему? Вы не можете просто создать отношение между Person и Group, поэтому вы должны указать все детали отношения, требуемые промежуточной моделью Membership. Простые методы add, create и присваивание не предоставляют возможности определить дополнительные детали. Поэтому они отключены в отношения вида многие-к-многим с использованием промежуточной модели. Единственный вариант создания данного вида отношений, заключается в создании экземпляров промежуточной модели.<br />
<br />
Метод remove отключен по этим же причинам. Однако вы можете использовать метод clear() для удаления всех отношений вида многие-к-многим отношений экземпляра:<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="78525514"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="78525514" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">beatles.<span class="me1">members</span>.<span class="me1">clear</span><span class="br0">&#40;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Итак, вы создали отношения вида многие-к-многим путем создания экземпляров промежуточной модели, теперь вы можете оформлять запросы. Так же как и и в случае с нормальным вариантом отношений, вы можете составлять запросы, используя атрибуты модели:<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="488100290"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="488100290" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1"><span class="co1">#ищет все группы с members, содержащей музыкантов (Person), с именем начинающимся на 'Paul'</span>
Group.<span class="me1">objects</span>.<span class="kw2">filter</span><span class="br0">&#40;</span>members__name__startswith<span class="sy0">=</span><span class="st0">'Paul'</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Так как вы используете промежуточную модель, вы также можете оформлять запросы, используя атрибуты модели-посредника:<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="471907971"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="471907971" style="height: 94px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
</pre></td><td class="de1"><pre class="de1"><span class="co1"># ищет всех музыкантов, которые присоединились к группе The Beatles после 1.1.1961</span>
Person.<span class="me1">objects</span>.<span class="kw2">filter</span><span class="br0">&#40;</span>
&nbsp; &nbsp; group__name<span class="sy0">=</span><span class="st0">'The Beatles'</span><span class="sy0">,</span>
&nbsp; &nbsp; membership__date_joined__gt<span class="sy0">=</span>date<span class="br0">&#40;</span><span class="nu0">1961</span><span class="sy0">,</span><span class="nu0">1</span><span class="sy0">,</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>
<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">[&lt;Person: Ringo Starr]</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Вы можете получить данные непосредственно из модели Membership:<br />
<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="264695077"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="264695077" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1">ringos_membership <span class="sy0">=</span> Membership.<span class="me1">objects</span>.<span class="me1">get</span><span class="br0">&#40;</span>group<span class="sy0">=</span>beatles<span class="sy0">,</span> person<span class="sy0">=</span>ringo<span class="br0">&#41;</span>
ringos_membership.<span class="me1">date_joined</span></pre></td></tr></table></div></td></tr></tbody></table></div>
<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">datetime.date(1962, 8, 16)</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table><div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="547328783"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="547328783" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">ringos_membership.<span class="me1">invite_reason</span></pre></td></tr></table></div></td></tr></tbody></table></div>
<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">u'Needed a new drummer.'</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Другой способ - используя обратную связь объекта модели Person:<br />
<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="417786337"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="417786337" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1">ringos_membership <span class="sy0">=</span> ringo.<span class="me1">membership_set</span>.<span class="me1">get</span><span class="br0">&#40;</span>group<span class="sy0">=</span>beatles<span class="br0">&#41;</span>
ringos_membership.<span class="me1">date_joined</span></pre></td></tr></table></div></td></tr></tbody></table></div>
<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">datetime.date(1962, 8, 16)</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table><div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="260570007"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="260570007" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">ringos_membership.<span class="me1">invite_reason</span></pre></td></tr></table></div></td></tr></tbody></table></div>
<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">u'Needed a new drummer.'</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Вотс. В принципе этот пример можно найти и в оф документации. Но пойдем дальше. Возьмем тот самый случай с models.ManyToManyField('self',symmetrica l=False):<br />
<br />
<br />
<div align="center"><font size="4"><b>Несимметричные m2m</b></font></div><br />
<br />
(пример со англоязычной ветки <a rel="nofollow noopener noreferrer" href="https://stackoverflow.com/questions/9712764/for-django-recursive-manytomanyfields-can-related-name-override-symmetrical-fal" target="_blank" title="https://stackoverflow.com/questions/9712764/for-django-recursive-manytomanyfields-can-related-name-override-symmetrical-fal">стэковерфлоу</a>): <br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="110043619"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="110043619" style="height: 286px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="de1"><pre class="de1"><span class="kw1">class</span> Author<span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; <span class="kw3">user</span> <span class="sy0">=</span> models.<span class="me1">OneToOneField</span><span class="br0">&#40;</span>User<span class="sy0">,</span> parent_link<span class="sy0">=</span><span class="kw2">True</span><span class="br0">&#41;</span>
&nbsp; &nbsp; introduction <span class="sy0">=</span> models.<span class="me1">TextField</span><span class="br0">&#40;</span>blank<span class="sy0">=</span><span class="kw2">True</span><span class="br0">&#41;</span>
&nbsp; &nbsp; pictures <span class="sy0">=</span> models.<span class="me1">ManyToManyField</span><span class="br0">&#40;</span><span class="st0">'Graphic'</span><span class="sy0">,</span> related_name<span class="sy0">=</span><span class="st0">'users'</span><span class="sy0">,</span> null<span class="sy0">=</span><span class="kw2">True</span><span class="br0">&#41;</span>
&nbsp; &nbsp; organizations <span class="sy0">=</span> models.<span class="me1">ManyToManyField</span><span class="br0">&#40;</span><span class="st0">'Organization'</span><span class="sy0">,</span> related_name<span class="sy0">=</span><span class="st0">'members'</span><span class="br0">&#41;</span>
&nbsp; &nbsp; expertise <span class="sy0">=</span> models.<span class="me1">ManyToManyField</span><span class="br0">&#40;</span><span class="st0">'Tag'</span><span class="sy0">,</span> related_name<span class="sy0">=</span><span class="st0">'experts'</span><span class="sy0">,</span> null<span class="sy0">=</span><span class="kw2">True</span><span class="br0">&#41;</span>
&nbsp; &nbsp; interests <span class="sy0">=</span> models.<span class="me1">ManyToManyField</span><span class="br0">&#40;</span><span class="st0">'Tag'</span><span class="sy0">,</span> related_name<span class="sy0">=</span><span class="st0">'interested_in'</span><span class="sy0">,</span> null<span class="sy0">=</span><span class="kw2">True</span><span class="br0">&#41;</span>
&nbsp; &nbsp; saved_articles <span class="sy0">=</span> models.<span class="me1">ManyToManyField</span><span class="br0">&#40;</span>Article<span class="sy0">,</span> related_name<span class="sy0">=</span><span class="st0">'favorited_by'</span><span class="sy0">,</span> null<span class="sy0">=</span><span class="kw2">True</span><span class="sy0">,</span> through<span class="sy0">=</span><span class="st0">'SavedArticles'</span><span class="br0">&#41;</span>
&nbsp; &nbsp; authors_followed <span class="sy0">=</span> models.<span class="me1">ManytoManyField</span><span class="br0">&#40;</span><span class="st0">'self'</span><span class="sy0">,</span> related_name<span class="sy0">=</span><span class="st0">'following_authors'</span><span class="sy0">,</span> null<span class="sy0">=</span><span class="kw2">True</span><span class="sy0">,</span> through<span class="sy0">=</span><span class="st0">'FollowedAuthors'</span><span class="sy0">,</span> symmetrical<span class="sy0">=</span><span class="kw2">False</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span class="kw1">class</span> FollowedAuthors<span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; author <span class="sy0">=</span> models.<span class="me1">ForeignKey</span><span class="br0">&#40;</span>Author<span class="br0">&#41;</span>
&nbsp; &nbsp; trustee <span class="sy0">=</span> models.<span class="me1">ForeignKey</span><span class="br0">&#40;</span>Author<span class="br0">&#41;</span>
&nbsp; &nbsp; notes <span class="sy0">=</span> models.<span class="me1">TextField</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; tags <span class="sy0">=</span> models.<span class="me1">ManyToManyField</span><span class="br0">&#40;</span><span class="st0">'Tag'</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Как видно здесь authors_followed объявлен как m2m c symmetrical=False. Что ж. С ними можно работать так: <br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="603085281"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="603085281" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">MyAuthor.<span class="me1">following_authors</span>.<span class="kw2">all</span><span class="br0">&#40;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>вернет авторов, следующих за MyAuthor<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="71741953"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="71741953" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">MyAuthor.<span class="me1">author_followed</span>.<span class="kw2">all</span><span class="br0">&#40;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>вернет авторов, за которыми следит MyAuthor<br />
<br />
Так же хочу обратить внимание на возможную необходимость объявить on_delete=models.CASCADE в m2m поле, как <a rel="nofollow noopener noreferrer" href="https://stackoverflow.com/questions/37561900/many-to-many-return-only-objects-from-symmetrical-relationship" target="_blank" title="https://stackoverflow.com/questions/37561900/many-to-many-return-only-objects-from-symmetrical-relationship">тут</a>: <br />
<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="731826502"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="731826502" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1"><span class="kw1">class</span> Relationship<span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; from_person <span class="sy0">=</span> models.<span class="me1">ForeignKey</span><span class="br0">&#40;</span>User<span class="sy0">,</span> on_delete<span class="sy0">=</span>models.<span class="me1">CASCADE</span><span class="sy0">,</span> related_name<span class="sy0">=</span><span class="st0">&quot;from_person&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; to_person <span class="sy0">=</span> models.<span class="me1">ForeignKey</span><span class="br0">&#40;</span>User<span class="sy0">,</span> on_delete<span class="sy0">=</span>models.<span class="me1">CASCADE</span><span class="sy0">,</span> related_name<span class="sy0">=</span><span class="st0">&quot;to_person&quot;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Это может пригодиться, если вы хотите оборвать все связи при удалении персоны, например :)<br />
<br />
Кстати интересен пример выборки к нему: <br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="434884943"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="434884943" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">User.<span class="me1">objects</span>.<span class="kw2">filter</span><span class="br0">&#40;</span>from_person__from_person__in<span class="sy0">=</span>request.<span class="kw3">user</span>.<span class="me1">friends</span>.<span class="kw2">all</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> from_person__to_person<span class="sy0">=</span>request.<span class="kw3">user</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Неплохо, неправда ли?</div>

]]></content:encoded>
			<dc:creator>netBool</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/125422/5193.html</guid>
		</item>
		<item>
			<title>Что особенного в переопределении конструктора модели Django?</title>
			<link>https://www.cyberforum.ru/blogs/125422/5136.html</link>
			<pubDate>Wed, 14 Feb 2018 10:31:05 GMT</pubDate>
			<description>Доброго дня и настроения всем любителям Джанго!  
 
Эта статья больше рассчитана на аудиторию...</description>
			<content:encoded><![CDATA[<div>Доброго дня и настроения всем любителям Джанго! <br />
<br />
Эта статья больше рассчитана на аудиторию начинающих джангистов, но предполагается, что читатель владеет основами языка. Все программеры, более менее освоившие python, знают что такое наследование, конструкторы и переопределение и наверняка пользовались этим не раз. Наверняка вам приходилось переопределять конструктор родителя, как то: <br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="85918296"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="85918296" style="height: 174px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
</pre></td><td class="de1"><pre class="de1"><span class="kw1">class</span> Car: &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="sy0">,</span> w_a<span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">weight_auto</span> <span class="sy0">=</span> w_a 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">koleco</span> <span class="sy0">=</span> <span class="nu0">4</span>
&nbsp;
<span class="kw1">class</span> Kran<span class="br0">&#40;</span>Car<span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span>w_a<span class="sy0">,</span> weight_all<span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">super</span><span class="br0">&#40;</span>Volc<span class="sy0">,</span> <span class="kw2">self</span><span class="br0">&#41;</span>.<span class="kw4">__init__</span><span class="br0">&#40;</span>w_a<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">weight_allpwed</span><span class="sy0">=</span> <span class="kw2">self</span>.<span class="me1">weight_all</span></pre></td></tr></table></div></td></tr></tbody></table></div>В этом примере мы создали класс Car, в конструкторе которого определили два поля. В наследуемом классе Kran мы переопределили конструктор, вызвав в нем родительский конструктор и добавив поле weight_allowed. Это простой пример<br />
<br />
В django мы имеем дело с моделями, которые по сути представляют из себя такие же классы, которые можно наследовать и в которых можно переопределять методы. И казалось бы, что может быть проще, но... <br />
<br />
Есть один нюанс. Если вы попробуете провернуть трюк с переопределением __init__, как в примере выше, вы можете натолкнуться на айсберг. <br />
<br />
Нет, не то, чтобы разработчики джанго запретили переопределять конструктор, но официально это не советуют: <br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">You may be tempted to customize the model by overriding the __init__ method. If you do so, however, take care not to change the calling signature as any change may prevent the model instance from being saved. Rather than overriding __init__, try using one of these approaches:</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Если по русски, то<br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">Возможно вам захочется переопределить метод __init__. В таком случае не переопределяйте сигнатуру вызова этого метода, иначе объект модели может не сохраняться. Вместо переопределения __init__ лучше используйте один из следующих подходов:</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>И предлагают два варианта: <br />
1. Добавить метод класса в модель:<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="186680842"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="186680842" style="height: 190px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
</pre></td><td class="de1"><pre class="de1"><span class="kw1">class</span> Book<span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; title <span class="sy0">=</span> models.<span class="me1">CharField</span><span class="br0">&#40;</span>max_length<span class="sy0">=</span><span class="nu0">100</span><span class="br0">&#41;</span>
&nbsp;
&nbsp; &nbsp; <span class="sy0">@</span><span class="kw2">classmethod</span>
&nbsp; &nbsp; <span class="kw1">def</span> create<span class="br0">&#40;</span>cls<span class="sy0">,</span> title<span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; book <span class="sy0">=</span> cls<span class="br0">&#40;</span>title<span class="sy0">=</span>title<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># do something with the book</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> book
&nbsp;
book <span class="sy0">=</span> Book.<span class="me1">create</span><span class="br0">&#40;</span><span class="st0">&quot;Pride and Prejudice&quot;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>2. Добавить метод в менеджер модели(лучший вариант):<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="753107982"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="753107982" style="height: 222px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="de1"><pre class="de1"><span class="kw1">class</span> BookManager<span class="br0">&#40;</span>models.<span class="me1">Manager</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; <span class="kw1">def</span> create_book<span class="br0">&#40;</span><span class="kw2">self</span><span class="sy0">,</span> title<span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; book <span class="sy0">=</span> <span class="kw2">self</span>.<span class="me1">create</span><span class="br0">&#40;</span>title<span class="sy0">=</span>title<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># do something with the book</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> book
&nbsp;
<span class="kw1">class</span> Book<span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; title <span class="sy0">=</span> models.<span class="me1">CharField</span><span class="br0">&#40;</span>max_length<span class="sy0">=</span><span class="nu0">100</span><span class="br0">&#41;</span>
&nbsp;
&nbsp; &nbsp; objects <span class="sy0">=</span> BookManager<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
book <span class="sy0">=</span> Book.<span class="me1">objects</span>.<span class="me1">create_book</span><span class="br0">&#40;</span><span class="st0">&quot;Pride and Prejudice&quot;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>И нет проблем, если вам всего лишь нужно переопределить создание модели... Тогда на этих примерах и ссылкой на оф.док можно и закончить. Но вдруг вам надо все-таки переопределить именно конструктор... Для чего?<br />
<br />
Например, у менеджера моделей есть такой удобный метод, как create. Для не особо искушенных я отмечу, что он не только создает модель, но так же и делает ее save(). В общем-то все и началось с того, что я решил использовать именно ее в своих вью. Конечно, можно ее использовать просто передавая именнованные параметры в аргументы без всякого переопределения. Зачем извращаться? <br />
<br />
Но что делать, если вы хотите передать в качестве параметра какой-то флаг или значение, которое не является полем модели и класса вообще, но на основе этого значения выполнялась бы какая-то логика, в результате выполнения которой полю модели должно быть присвоено значение. Скажете вы - ну и нафиг, всю эту логику можно прописать во view. Хорошо. Но что делать, если с этой моделью нуно очень часто create()? Прописывать ее каждый раз? Ну тоже вариант. Хорошо. Но мы не ищем легких путей<br />
<br />
Для начала я бы хотел рассмотреть несколько примеров, как и почему не работает переопределение сигнатуры конструкторов моделей. Например:<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="15674977"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="15674977" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1"><span class="kw1">class</span> Dialogue<span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; Partakers <span class="sy0">=</span> ArrayField<span class="br0">&#40;</span>models.<span class="me1">BigIntegerField</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> null<span class="sy0">=</span><span class="kw2">False</span><span class="sy0">,</span> unique<span class="sy0">=</span><span class="kw2">True</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="sy0">,</span> partrs<span class="sy0">,</span> *args<span class="sy0">,</span> **kwargs<span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">super</span><span class="br0">&#40;</span>Dialogue<span class="sy0">,</span> <span class="kw2">self</span><span class="br0">&#41;</span>.<span class="kw4">__init__</span><span class="br0">&#40;</span>*args<span class="sy0">,</span> **kwargs<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">Partakers</span> <span class="sy0">=</span> partrs</pre></td></tr></table></div></td></tr></tbody></table></div>Это класс диалог, Partakers - это участники диалога. Далее я создаю его так: <br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="214266355"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="214266355" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">Dialog <span class="sy0">=</span> Dialogue.<span class="me1">objects</span>.<span class="me1">create</span><span class="br0">&#40;</span>partrs<span class="sy0">=</span><span class="br0">&#91;</span><span class="kw2">int</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">request</span>.<span class="me1">POST</span><span class="br0">&#91;</span><span class="st0">'userid'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>И создав, я обнаруживаю, что он работает вопреки всем заявлениям разработчиков: модель создалась, корректно прописалась в БД. В общем, решив, что они там чего-то перепутали, я продолжил работу над другими моделями<br />
<br />
Но какого же было мое удивление, когда я попытался выполнить следующее: <br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="799392538"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="799392538" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw2">id</span> <span class="sy0">=</span> Dialogue.<span class="me1">objects</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="kw2">id</span><span class="sy0">=</span><span class="nu0">1</span><span class="br0">&#41;</span>.<span class="kw2">id</span></pre></td></tr></table></div></td></tr></tbody></table></div>В переменную id вместо индекса я получил массив ArrayField!!! =-O<br />
<br />
Впрочем, если рассказывать по порядку, то обнаружил это не сразу:wall:<br />
<br />
Сперва я создал модель сообщения:<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="371573438"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="371573438" style="height: 126px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
</pre></td><td class="de1"><pre class="de1"><span class="kw1">class</span> Message<span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:
&nbsp;
&nbsp; &nbsp; Dialog <span class="sy0">=</span> models.<span class="me1">ForeignKey</span><span class="br0">&#40;</span>Dialogue<span class="br0">&#41;</span>
&nbsp; &nbsp; Sender <span class="sy0">=</span> models.<span class="me1">ForeignKey</span><span class="br0">&#40;</span>Profile<span class="br0">&#41;</span>
&nbsp; &nbsp; Content <span class="sy0">=</span> models.<span class="me1">TextField</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; DateTime <span class="sy0">=</span> models.<span class="me1">DateTimeField</span><span class="br0">&#40;</span><span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>И переопределил ее конструктор: <br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="45382408"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="45382408" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1"><span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="sy0">,</span> receiver<span class="sy0">,</span> sender<span class="sy0">,</span> content<span class="sy0">,</span>*args<span class="sy0">,</span>**kwargs<span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">super</span><span class="br0">&#40;</span>Message<span class="sy0">,</span> <span class="kw2">self</span><span class="br0">&#41;</span>.<span class="kw4">__init__</span><span class="br0">&#40;</span>*args<span class="sy0">,</span>**kwargs<span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>(ну а почему бы нет?) <br />
Но на строке<br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="728685377"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="728685377" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">msg <span class="sy0">=</span> Message.<span class="me1">objects</span>.<span class="me1">create</span><span class="br0">&#40;</span>sender<span class="sy0">=</span>request.<span class="kw3">user</span><span class="sy0">,</span> content<span class="sy0">=</span>request.<span class="me1">POST</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">'value'</span><span class="sy0">,</span> <span class="st0">''</span><span class="br0">&#41;</span><span class="sy0">,</span>receiver<span class="sy0">=</span>receivers<span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Интерпретатор мне постоянно стал выбрасывать ошибку: <br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message"><b>TypeError: __init__() takes exactly 2 arguments (3 given)</b></div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Которая поставила меня в полный тупик. <br />
Попробовал через конструктор Message(...). То же самое. Тогда я пошел спрашивать у гугла, и тут вспомнил о советах разработчиков так не делать: не переопределять конструктор, а если переопределять, то не менять сигнатуру. <br />
Странно, подумал я, там они писали, что модель может всего лишь не сохраниться, а тут... <br />
Я убрал все лишнее, оставил только **kwargs и туда помимо всех полей передал переменную для выполнения логики. Замечу, что делал я уже все не через create менеджера, а через обычный конструктор Message(...). И о чудо, модель была создана и не выдала ошибку... Тогда я попробовал все это сделать через create. Но ошибка вернулась<br />
Собственно, оказывается для create даже в kwargs не должно приходить ничего лишнего<br />
<br />
В чем же проблема? <br />
<br />
Мы знаем, что python ооп-ный язык и поддерживает не только наследование, но и полиморфизм :) <br />
Метод create работает непосредственно с классом Model и его конструктором, с сигнатурой конструктора Model и ни с какой другой. В этом методе идет перечисление полей args и kwargs, в которых предполагаются поля нашей пользовательской модели и ничего лишнего. <br />
<br />
Вопрос, что же делать, если все-таки есть желание работать через create?<br />
<br />
Зная принцип работы create мы можем его использовать как хотим при одном маленьком условии: при вызове конструктора Model надо привести его сигнатуру в соответствии с ожидаемой. Например, так: <br />
<div class="codeblock"><table class="python"><thead><tr><td colspan="2" id="73707996"  class="head">Python</td></tr></thead><tbody><tr class="li1"><td><div id="73707996" style="height: 158px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="sy0">,</span> **kwargs<span class="br0">&#41;</span>: <span class="co1">#</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> kwargs.<span class="me1">has_key</span><span class="br0">&#40;</span><span class="st0">'receiver'</span><span class="br0">&#41;</span>: receiver <span class="sy0">=</span> kwargs<span class="br0">&#91;</span><span class="st0">'receiver'</span><span class="br0">&#93;</span><span class="sy0">;</span> kwargs.<span class="me1">pop</span><span class="br0">&#40;</span><span class="st0">'receiver'</span><span class="br0">&#41;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">super</span><span class="br0">&#40;</span>Message<span class="sy0">,</span> <span class="kw2">self</span><span class="br0">&#41;</span>.<span class="kw4">__init__</span><span class="br0">&#40;</span>**kwargs<span class="br0">&#41;</span> <span class="co1">#receiver, sender, content,</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">dir</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="kw4">__contains__</span><span class="br0">&#40;</span><span class="st0">'receiver'</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#далее ваш код</span></pre></td></tr></table></div></td></tr></tbody></table></div>В вышеприведенном коде в kwargs пришло одно неожидаемое значение: 'receiver'. Сохраняю его в отдельную переменную, удаляю из kwargs и спокойно вызываю конструктор родителя.<br />
 <br />
Надеюсь, статья была полезной. Хоть кому-нибудь:) Писал на скорую руку. Может быть, куча ошибок. Но общий принцип и идею, думаю, передал</div>

]]></content:encoded>
			<dc:creator>netBool</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/125422/5136.html</guid>
		</item>
	</channel>
</rss>
