среда, 21 января 2015 г.

Статические поля в generic-классах

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/static-field-in-generic-type/.


Сегодня мы кратко поговорим о статических полях в generic-классах. Тема простая, но у некоторых разработчиков она вызывает трудности. Итак, задачка: что выведет следующий код?

class Foo<T>
{
  public static int Bar;
}
void Main()
{
  Foo<int>.Bar++;
  Console.WriteLine(Foo<double>.Bar);
}

понедельник, 24 ноября 2014 г.

List.ForEach в .NET 4.5

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/listforeach-net-45/.


Продолжим обсуждать тему изменения коллекции внутри цикла foreach. Следующий код

var list = new List<int> { 1, 2 };
foreach (var i in list)
{
    if (i == 1)
        list.Add(3);
    Console.WriteLine(i);
}
выбросит InvalidOperationException. А как думаете, что случится при выполнении цикла через List<T>.ForEach?

var list = new List<int> { 1, 2 };
list.ForEach(i =>
{
    if (i == 1)
        list.Add(3);
    Console.WriteLine(i);
});

пятница, 21 ноября 2014 г.

Ещё раз об экранировании URI в .NET

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/uri-escaping/.


Сегодня на StackOverflow мне попался интересный вопрос: «Unit test ReSharper and NUnit give different results». Суть заключалась в том, что ReSharper и NUnit дают разные результаты при экранировании URI. Я решил немножко углубиться в эту проблему. Сегодняшний пост продолжает недавно начатую мной тему «Об экранировании слеша в .NET».

среда, 19 ноября 2014 г.

Сайд-эффект внутренней реализации List

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/list-version-side-effect/.


Если вы делаете foreach по некоторому List-у, то менять итерируемый лист внутри цикла крайне не рекомендуется, ведь это верный способ получить InvalidOperationException. А теперь загадка: как думаете, что случится со следующим кодом:

var list = new List<int> { 0, 1, 2 };
foreach(var x in list)
{
  if (x == 0)
  {
    for (int i = int.MinValue; i < int.MaxValue; i++)
      list[0] = 0;
    list.Add(3);
  }
  Console.WriteLine(x);
}

Правильный ответ: этот код замечательно отработает.

четверг, 13 ноября 2014 г.

Об экранировании слеша в .NET

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/uri-escaping/.


Загадка на сегодня: что выведет код?

var uri = new Uri("http://localhost/%2F1");
Console.WriteLine(uri.OriginalString);
Console.WriteLine(uri.AbsoluteUri);

Правильный ответ: зависит. Давайте немножко поразбираемся.

вторник, 11 ноября 2014 г.

Nullable-арифметика

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/cheatsheet-nullable/.


Что будет, если null поделить на ноль? А сколько будет null | true? А null & true? А ((string)null + null)?

Практика подсказывает, что C#-разработчики зачастую не особо задумываются о том, как будут оцениваться выражения, если один из операндов равен null. Поэтому я решил составить небольшую шпаргалку на эту тему.

понедельник, 10 ноября 2014 г.

About UTF-8 conversions in Mono

Blog has been moved. Actual post url: http://aakinshin.net/en/blog/dotnet/mono-utf8-conversions/.


This post is a logical continuation of the Jon Skeet's blog post “When is a string not a string?”. Jon showed very interesting things about behavior of ill-formed Unicode strings in .NET. I wondered about how similar examples will work on Mono. And I have got very interesting results.

Experiment 1: Compilation

Let's take the Jon's code with a small modification. We will just add text null check in DumpString:

using System;
using System.ComponentModel;
using System.Text;
using System.Linq;
 
[Description(Value)]
class Test
{
    const string Value = "X\ud800Y";
 
    static void Main()
    {
        var description = (DescriptionAttribute)typeof(Test).
            GetCustomAttributes(typeof(DescriptionAttribute), true)[0];
        DumpString("Attribute", description.Description);
        DumpString("Constant", Value);
    }
 
    static void DumpString(string name, string text)
    {
        Console.Write("{0}: ", name);
        if (text != null)
        {
            var utf16 = text.Select(c => ((uint) c).ToString("x4"));
            Console.WriteLine(string.Join(" ", utf16));
        }
        else
            Console.WriteLine("null");
    }
}

среда, 29 октября 2014 г.

Endianness в .NET

Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/endianness/.


Рассмотрим простую задачку: что выведет следующий код?

[StructLayout(LayoutKind.Explicit)]
struct UInt16Wrapper
{
  [FieldOffset(0)]
  public UInt16 Value;
  [FieldOffset(0)]
  public Byte Byte1;
  [FieldOffset(1)]
  public Byte Byte2;
}
void Main()
{
  var uint16 = new UInt16Wrapper();
  uint16.Value = 1 + 2 * 256;
  Console.WriteLine(uint16.Byte1);
  Console.WriteLine(uint16.Byte2);
}

Полагаю, что внимательный читатель должен обратить внимание на название поста и дать правильный ответ: «зависит». Сегодня мы немного поговорим о том, как в .NET обстоят дела с порядком байтов.

четверг, 2 октября 2014 г.

Задачник.NET

Этот пост предназначается всем любителям платформы .NET и языка C#. Думаю, многие встречали на просторах сети разнообразные задачки на понимание тех или иных особенностей платформы или языка. Я большой любитель подобных задачек и головоломок. Они помогают глубже понять определённые области и повысить собственные программистские навыки. Однажды я решил сделать подборку подобных задачек, чтобы можно было показывать другим людям и обсуждать нюансы работы с .NET/C#. Когда задачек накопилось достаточное количество, появилась новая мысль — оформить мою подборку в виде книжки. Вашему вниманию предоставляется текущий вариант этого сочинения под названием «Задачник.NET».

Читать online
Скачать PDF-версию
Исходные коды на GitHub