SlideShare una empresa de Scribd logo
1 de 27
Descargar para leer sin conexión
Об особенностях использования значимых типов в .NET
Андрей Акиньшин

Барнаульское сообщество .NET разработчиков
bug.ineta.ru
www.facebook.com/groups/dotnetbarnaul/
Структуры

•
•
•
•
•

Копирование по значению
Поддержка boxed и unboxed формы
Всегда инициализированы
Методы из Equals, GetHashCode из System.ValueType
Не могут быть базовыми типами
Изменяемые значимые типы
public struct Point
{
public int X, Y;
public void Move(int dx, int dy)
{
X += dx;
Y += dy;
}
}
public class Circle
{
public Point Center; // Поле
}
var circle = new Circle();
circle.Center = new Point { X = 0, Y = 0 };
circle.Center.Move(5, 5);
Console.WriteLine(circle.Center.X);
Изменяемые значимые типы
public struct Point
{
public int X, Y;
public void Move(int dx, int dy)
{
X += dx;
Y += dy;
}
}
public class Circle
{
public Point Center { get; set; } // Свойство
}
var circle = new Circle();
circle.Center = new Point { X = 0, Y = 0 };
circle.Center.Move(5, 5);
Console.WriteLine(circle.Center.X);
Изменяемые значимые типы
Будут проблемы:
// 1. Property
public class Circle
{
public Point Center { get; set; }
}
// 2. Readonly field
public class Circle
{
public readonly Point Center = new Point();
}
// 3. IList
var points = new List<Point>();
Изменяемые значимые типы

public struct Enumerator : IEnumerator<T>, IDisposable,
IEnumerator
var x = new
{
Items = new List<int> { 1, 2, 3 }.GetEnumerator()
};
while (x.Items.MoveNext())
Console.WriteLine(x.Items.Current);
Изменяемые значимые типы

struct Disposable : IDisposable
{
public bool Disposed { get; private set; }
public void Dispose() { Disposed = true; }
}
var d = new Disposable();
using (d)
{
// Some code
}
Console.WriteLine(d.Disposed);
Упаковка и распаковка
// 1
var arrayList = new ArrayList();
var p = new Point();
arrayList.Add(p);
// Упаковка
p = (Point) arrayList[0];
// Распаковка
Упаковка и распаковка
// 1
var arrayList = new ArrayList();
var p = new Point();
arrayList.Add(p);
// Упаковка
p = (Point) arrayList[0];
// Распаковка
// 2
Int32 x = 5;
Object o = x;
// Упаковка
Int16 y = (Int16) o;
// InvalidCastException
Int16 z = (Int16)(Int32) o; // Распаковка и приведение
Упаковка и распаковка
// 1
var arrayList = new ArrayList();
var p = new Point();
arrayList.Add(p);
// Упаковка
p = (Point) arrayList[0];
// Распаковка
// 2
Int32 x = 5;
Object o = x;
// Упаковка
Int16 y = (Int16) o;
// InvalidCastException
Int16 z = (Int16)(Int32) o; // Распаковка и приведение
// 3
Int32 x = 1;
Object y = x;
x = 2;
Console.WriteLine(x + "/" + (Int32)y);// "2/1"
Упаковка и распаковка
interface IChangeable
{
void Change(int x, int y);
}
struct Point : IChangeable
{
public int X, Y;
public void Change(int x, int y)
{
X = x;
Y = y;
}
public override string ToString()
{
return X + "," + Y;
}
}
Упаковка и распаковка
var p = new Point {X = 1, Y = 1};
Console.WriteLine(p);
p.Change(2, 2);
Console.WriteLine(p);
Object o = p;
Console.WriteLine(o);
((Point) o).Change(3, 3);
Console.WriteLine(o);
((IChangeable)p).Change(4, 4);
Console.WriteLine(p);
((IChangeable)o).Change(5, 5);
Console.WriteLine(o);
Конструкторы по умолчанию

• .NET поддерживает конструкторы по умолчанию для

структур
Конструкторы по умолчанию

• .NET поддерживает конструкторы по умолчанию для

структур
• А C# — нет
Конструкторы по умолчанию

• .NET поддерживает конструкторы по умолчанию для

структур
• А C# — нет
• Но мы всё равно создадим структуру с конструктором
по умолчанию, которую назовём MyStruct
Конструкторы по умолчанию

// Вспомогательные методы
static T CreateAsDefault<T>() { return default(T); }
static T CreateWithNew<T>() where T : new() { return new T(); }
// Вызывается
var m = Activator.CreateInstance(typeof(MyStruct));
var m = new MyStruct();
// Не вызывается
var m = default(MyStruct);
var m = CreateWithNew<MyStruct>();
var m = CreateAsDefault<MyStruct>();
var array = new MyStruct[100];
GetHashCode()

• Быстрая версия

(Структура не имеет ссылочных полей, а между её
полями нет свободного места)
Используем Xor каждых 4 байта структуры
• Медленная версия
Используем GetHashCode первого нестатичного поля
GetHashCode()

var a1 = new KeyValuePair<int, int>(1, 2);
var a2 = new KeyValuePair<int, int>(1, 3);
Console.WriteLine(a1.GetHashCode()); // 1033533110
Console.WriteLine(a2.GetHashCode()); // 1033533111
var b1 = new KeyValuePair<int, string>(1, "x");
var b2 = new KeyValuePair<int, string>(1, "y");
Console.WriteLine(b1.GetHashCode()); // -1888265882
Console.WriteLine(b2.GetHashCode()); // -1888265882
Equals()
public override bool Equals (Object obj) {
// ...
FieldInfo[] thisFields = thisType.GetFields(
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.NonPublic);
for (int i=0; i<thisFields.Length; i++) {
thisResult = ((RtFieldInfo)thisFields[i]).
InternalGetValue(thisObj,false);
thatResult = ((RtFieldInfo)thisFields[i]).
InternalGetValue(obj, false);
if (thisResult == null) {
if (thatResult != null)
return false;
} else if (!thisResult.Equals(thatResult))
return false;
}
return true;
}
Equals()
var redName = Color.Red;
var redArgb = Color.FromArgb(255, 255, 0, 0);
Console.WriteLine(redName == redArgb);
Equals()
var redName = Color.Red;
var redArgb = Color.FromArgb(255, 255, 0, 0);
Console.WriteLine(redName == redArgb);
public struct Color {
private readonly long value;
private readonly string name;
private readonly short knownColor, state;
public static bool operator ==(Color left, Color right) {
if (left.value == right.value &&
left.state == right.state &&
left.knownColor == right.knownColor) {
if (left.name == right.name)
return true;
if (left.name == (object) null ||
right.name == (object) null)
return false;
return left.name.Equals(right.name);
}
return false;
}
}
Размещение в памяти
public struct S1
{
public byte Byte1;
public int Int1;
}
public struct S2
{
public byte Byte1;
public byte Byte2;
public byte Byte3;
public byte Byte4;
public int Int1;
}
Console.WriteLine(Marshal.SizeOf(typeof(S1)));
Console.WriteLine(Marshal.SizeOf(typeof(S2)));
Размещение в памяти

[StructLayout(LayoutKind.Explicit)]
struct MyStruct
{
[FieldOffset(0)]
public Int16 Value;
[FieldOffset(0)]
public Byte LowByte;
}
var s = new MyStruct();
s.Value = 256 + 100;
Console.WriteLine(s.LowByte); // 100
Размещение в памяти
namespace System.Drawing {
public struct Color {
/**
* Shift count and bit mask for A, R, G, B
* components in ARGB mode!
*/
private const int ARGBAlphaShift = 24;
private const int ARGBRedShift
= 16;
private const int ARGBGreenShift = 8;
private const int ARGBBlueShift
= 0;
///
///
///
///
///
///
///
}
}

WARNING!!! WARNING!!! WARNING!!! WARNING!!!
WARNING!!! WARNING!!! WARNING!!! WARNING!!!
We can never change the layout of this class (adding
or removing or changing the order of member variables)
if you want to be compatible v1.0 version of the runtime
This is so that we can push into the runtime a custom
marshaller for OLE_COLOR to Color.
Хорошие книжки
Блоги

• http://msdn.microsoft.com/magazine/
• http://www.rsdn.ru/
• http://blogs.msdn.com/b/ericlippert/
• http://sergeyteplyakov.blogspot.ru/
• http://timyrguev.blogspot.ru/
• http://aakinshin.blogspot.ru/
Спасибо за внимание!

Más contenido relacionado

La actualidad más candente

20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
Computer Science Club
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Mikhail Kurnosov
 

La actualidad más candente (19)

Оптимизация производительности Python
Оптимизация производительности PythonОптимизация производительности Python
Оптимизация производительности Python
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибок
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о Boost
 
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“
Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“
Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“
 
Магия в Python: Дескрипторы. Что это?
Магия в Python: Дескрипторы. Что это?Магия в Python: Дескрипторы. Что это?
Магия в Python: Дескрипторы. Что это?
 
Продолжаем говорить про арифметику
Продолжаем говорить про арифметикуПродолжаем говорить про арифметику
Продолжаем говорить про арифметику
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building Blocks
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типов
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в Django
 
Progr labrab-4-2013-c++
Progr labrab-4-2013-c++Progr labrab-4-2013-c++
Progr labrab-4-2013-c++
 

Similar a Об особенностях использования значимых типов в .NET

Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-CШкола-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
Глеб Тарасов
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
Alex Tumanoff
 

Similar a Об особенностях использования значимых типов в .NET (20)

C sharp deep dive
C sharp deep diveC sharp deep dive
C sharp deep dive
 
C# Deep Dive
C# Deep DiveC# Deep Dive
C# Deep Dive
 
Язык программирования C#
Язык программирования C#Язык программирования C#
Язык программирования C#
 
C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному коду
 
[JAM 1.1] Clean Code (Paul Malikov)
[JAM 1.1] Clean Code (Paul Malikov)[JAM 1.1] Clean Code (Paul Malikov)
[JAM 1.1] Clean Code (Paul Malikov)
 
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-CШкола-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
 
Programming Java - Lecture 02 - Objects - Lavrentyev Fedor
Programming Java - Lecture 02 - Objects - Lavrentyev FedorProgramming Java - Lecture 02 - Objects - Lavrentyev Fedor
Programming Java - Lecture 02 - Objects - Lavrentyev Fedor
 
Groovy и Grails. Быстро и обо всём
Groovy и Grails. Быстро и обо всёмGroovy и Grails. Быстро и обо всём
Groovy и Grails. Быстро и обо всём
 
2.2 Стек вызовов
2.2 Стек вызовов2.2 Стек вызовов
2.2 Стек вызовов
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 
msumobi2. Лекция 1
msumobi2. Лекция 1msumobi2. Лекция 1
msumobi2. Лекция 1
 
Statis code analysis
Statis code analysisStatis code analysis
Statis code analysis
 
C# Desktop. Занятие 03.
C# Desktop. Занятие 03.C# Desktop. Занятие 03.
C# Desktop. Занятие 03.
 
Kotlin
KotlinKotlin
Kotlin
 
Распространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложенийРаспространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложений
 
Array Work C
Array Work CArray Work C
Array Work C
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
 
Bytecode
BytecodeBytecode
Bytecode
 

Más de Andrey Akinshin

Más de Andrey Akinshin (17)

Поговорим про performance-тестирование
Поговорим про performance-тестированиеПоговорим про performance-тестирование
Поговорим про performance-тестирование
 
Сложности performance-тестирования
Сложности performance-тестированияСложности performance-тестирования
Сложности performance-тестирования
 
Сложности микробенчмаркинга
Сложности микробенчмаркингаСложности микробенчмаркинга
Сложности микробенчмаркинга
 
Поговорим про память
Поговорим про памятьПоговорим про память
Поговорим про память
 
Кроссплатформенный .NET и как там дела с Mono и CoreCLR
Кроссплатформенный .NET и как там дела с Mono и CoreCLRКроссплатформенный .NET и как там дела с Mono и CoreCLR
Кроссплатформенный .NET и как там дела с Mono и CoreCLR
 
Теория и практика .NET-бенчмаркинга (25.01.2017, Москва)
 Теория и практика .NET-бенчмаркинга (25.01.2017, Москва) Теория и практика .NET-бенчмаркинга (25.01.2017, Москва)
Теория и практика .NET-бенчмаркинга (25.01.2017, Москва)
 
Let’s talk about microbenchmarking
Let’s talk about microbenchmarkingLet’s talk about microbenchmarking
Let’s talk about microbenchmarking
 
Теория и практика .NET-бенчмаркинга (02.11.2016, Екатеринбург)
Теория и практика .NET-бенчмаркинга (02.11.2016, Екатеринбург)Теория и практика .NET-бенчмаркинга (02.11.2016, Екатеринбург)
Теория и практика .NET-бенчмаркинга (02.11.2016, Екатеринбург)
 
Подружили CLR и JVM в Project Rider
Подружили CLR и JVM в Project RiderПодружили CLR и JVM в Project Rider
Подружили CLR и JVM в Project Rider
 
Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?
 
.NET 2015: Будущее рядом
.NET 2015: Будущее рядом.NET 2015: Будущее рядом
.NET 2015: Будущее рядом
 
Практические приёмы оптимизации .NET-приложений
Практические приёмы оптимизации .NET-приложенийПрактические приёмы оптимизации .NET-приложений
Практические приёмы оптимизации .NET-приложений
 
Поговорим о различных версиях .NET
Поговорим о различных версиях .NETПоговорим о различных версиях .NET
Поговорим о различных версиях .NET
 
Низкоуровневые оптимизации .NET-приложений
Низкоуровневые оптимизации .NET-приложенийНизкоуровневые оптимизации .NET-приложений
Низкоуровневые оптимизации .NET-приложений
 
Основы работы с Git
Основы работы с GitОсновы работы с Git
Основы работы с Git
 
Сборка мусора в .NET
Сборка мусора в .NETСборка мусора в .NET
Сборка мусора в .NET
 
Phd presentation
Phd presentationPhd presentation
Phd presentation
 

Об особенностях использования значимых типов в .NET

  • 1. Об особенностях использования значимых типов в .NET Андрей Акиньшин Барнаульское сообщество .NET разработчиков bug.ineta.ru www.facebook.com/groups/dotnetbarnaul/
  • 2. Структуры • • • • • Копирование по значению Поддержка boxed и unboxed формы Всегда инициализированы Методы из Equals, GetHashCode из System.ValueType Не могут быть базовыми типами
  • 3. Изменяемые значимые типы public struct Point { public int X, Y; public void Move(int dx, int dy) { X += dx; Y += dy; } } public class Circle { public Point Center; // Поле } var circle = new Circle(); circle.Center = new Point { X = 0, Y = 0 }; circle.Center.Move(5, 5); Console.WriteLine(circle.Center.X);
  • 4. Изменяемые значимые типы public struct Point { public int X, Y; public void Move(int dx, int dy) { X += dx; Y += dy; } } public class Circle { public Point Center { get; set; } // Свойство } var circle = new Circle(); circle.Center = new Point { X = 0, Y = 0 }; circle.Center.Move(5, 5); Console.WriteLine(circle.Center.X);
  • 5. Изменяемые значимые типы Будут проблемы: // 1. Property public class Circle { public Point Center { get; set; } } // 2. Readonly field public class Circle { public readonly Point Center = new Point(); } // 3. IList var points = new List<Point>();
  • 6. Изменяемые значимые типы public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator var x = new { Items = new List<int> { 1, 2, 3 }.GetEnumerator() }; while (x.Items.MoveNext()) Console.WriteLine(x.Items.Current);
  • 7. Изменяемые значимые типы struct Disposable : IDisposable { public bool Disposed { get; private set; } public void Dispose() { Disposed = true; } } var d = new Disposable(); using (d) { // Some code } Console.WriteLine(d.Disposed);
  • 8. Упаковка и распаковка // 1 var arrayList = new ArrayList(); var p = new Point(); arrayList.Add(p); // Упаковка p = (Point) arrayList[0]; // Распаковка
  • 9. Упаковка и распаковка // 1 var arrayList = new ArrayList(); var p = new Point(); arrayList.Add(p); // Упаковка p = (Point) arrayList[0]; // Распаковка // 2 Int32 x = 5; Object o = x; // Упаковка Int16 y = (Int16) o; // InvalidCastException Int16 z = (Int16)(Int32) o; // Распаковка и приведение
  • 10. Упаковка и распаковка // 1 var arrayList = new ArrayList(); var p = new Point(); arrayList.Add(p); // Упаковка p = (Point) arrayList[0]; // Распаковка // 2 Int32 x = 5; Object o = x; // Упаковка Int16 y = (Int16) o; // InvalidCastException Int16 z = (Int16)(Int32) o; // Распаковка и приведение // 3 Int32 x = 1; Object y = x; x = 2; Console.WriteLine(x + "/" + (Int32)y);// "2/1"
  • 11. Упаковка и распаковка interface IChangeable { void Change(int x, int y); } struct Point : IChangeable { public int X, Y; public void Change(int x, int y) { X = x; Y = y; } public override string ToString() { return X + "," + Y; } }
  • 12. Упаковка и распаковка var p = new Point {X = 1, Y = 1}; Console.WriteLine(p); p.Change(2, 2); Console.WriteLine(p); Object o = p; Console.WriteLine(o); ((Point) o).Change(3, 3); Console.WriteLine(o); ((IChangeable)p).Change(4, 4); Console.WriteLine(p); ((IChangeable)o).Change(5, 5); Console.WriteLine(o);
  • 13. Конструкторы по умолчанию • .NET поддерживает конструкторы по умолчанию для структур
  • 14. Конструкторы по умолчанию • .NET поддерживает конструкторы по умолчанию для структур • А C# — нет
  • 15. Конструкторы по умолчанию • .NET поддерживает конструкторы по умолчанию для структур • А C# — нет • Но мы всё равно создадим структуру с конструктором по умолчанию, которую назовём MyStruct
  • 16. Конструкторы по умолчанию // Вспомогательные методы static T CreateAsDefault<T>() { return default(T); } static T CreateWithNew<T>() where T : new() { return new T(); } // Вызывается var m = Activator.CreateInstance(typeof(MyStruct)); var m = new MyStruct(); // Не вызывается var m = default(MyStruct); var m = CreateWithNew<MyStruct>(); var m = CreateAsDefault<MyStruct>(); var array = new MyStruct[100];
  • 17. GetHashCode() • Быстрая версия (Структура не имеет ссылочных полей, а между её полями нет свободного места) Используем Xor каждых 4 байта структуры • Медленная версия Используем GetHashCode первого нестатичного поля
  • 18. GetHashCode() var a1 = new KeyValuePair<int, int>(1, 2); var a2 = new KeyValuePair<int, int>(1, 3); Console.WriteLine(a1.GetHashCode()); // 1033533110 Console.WriteLine(a2.GetHashCode()); // 1033533111 var b1 = new KeyValuePair<int, string>(1, "x"); var b2 = new KeyValuePair<int, string>(1, "y"); Console.WriteLine(b1.GetHashCode()); // -1888265882 Console.WriteLine(b2.GetHashCode()); // -1888265882
  • 19. Equals() public override bool Equals (Object obj) { // ... FieldInfo[] thisFields = thisType.GetFields( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i=0; i<thisFields.Length; i++) { thisResult = ((RtFieldInfo)thisFields[i]). InternalGetValue(thisObj,false); thatResult = ((RtFieldInfo)thisFields[i]). InternalGetValue(obj, false); if (thisResult == null) { if (thatResult != null) return false; } else if (!thisResult.Equals(thatResult)) return false; } return true; }
  • 20. Equals() var redName = Color.Red; var redArgb = Color.FromArgb(255, 255, 0, 0); Console.WriteLine(redName == redArgb);
  • 21. Equals() var redName = Color.Red; var redArgb = Color.FromArgb(255, 255, 0, 0); Console.WriteLine(redName == redArgb); public struct Color { private readonly long value; private readonly string name; private readonly short knownColor, state; public static bool operator ==(Color left, Color right) { if (left.value == right.value && left.state == right.state && left.knownColor == right.knownColor) { if (left.name == right.name) return true; if (left.name == (object) null || right.name == (object) null) return false; return left.name.Equals(right.name); } return false; } }
  • 22. Размещение в памяти public struct S1 { public byte Byte1; public int Int1; } public struct S2 { public byte Byte1; public byte Byte2; public byte Byte3; public byte Byte4; public int Int1; } Console.WriteLine(Marshal.SizeOf(typeof(S1))); Console.WriteLine(Marshal.SizeOf(typeof(S2)));
  • 23. Размещение в памяти [StructLayout(LayoutKind.Explicit)] struct MyStruct { [FieldOffset(0)] public Int16 Value; [FieldOffset(0)] public Byte LowByte; } var s = new MyStruct(); s.Value = 256 + 100; Console.WriteLine(s.LowByte); // 100
  • 24. Размещение в памяти namespace System.Drawing { public struct Color { /** * Shift count and bit mask for A, R, G, B * components in ARGB mode! */ private const int ARGBAlphaShift = 24; private const int ARGBRedShift = 16; private const int ARGBGreenShift = 8; private const int ARGBBlueShift = 0; /// /// /// /// /// /// /// } } WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! We can never change the layout of this class (adding or removing or changing the order of member variables) if you want to be compatible v1.0 version of the runtime This is so that we can push into the runtime a custom marshaller for OLE_COLOR to Color.
  • 26. Блоги • http://msdn.microsoft.com/magazine/ • http://www.rsdn.ru/ • http://blogs.msdn.com/b/ericlippert/ • http://sergeyteplyakov.blogspot.ru/ • http://timyrguev.blogspot.ru/ • http://aakinshin.blogspot.ru/