Skip to content

Instantly share code, notes, and snippets.

@Porges
Last active January 23, 2019 22:10
Show Gist options
  • Save Porges/f23e165ad5d6447ed1719f3a34b3fbe3 to your computer and use it in GitHub Desktop.
Save Porges/f23e165ad5d6447ed1719f3a34b3fbe3 to your computer and use it in GitHub Desktop.
Implementing Smalltalk "become" in C#
using System;
using System.Runtime.CompilerServices;
using System.Threading;
class Program
{
static void Main()
{
var x = new Person();
var y = new Dog();
Monitor.Enter(x);
{
Console.WriteLine($"x = {x}; y = {y}");
Swap(x, y);
Console.WriteLine($"x = {x}; y = {y}");
}
Monitor.Exit(y);
}
unsafe static void Swap<T, U>(T left, U right)
where T: class
where U: class
{
if (Unsafe.SizeOf<T>() != Unsafe.SizeOf<U>())
{
throw new ArgumentException("Too unsafe, even for me!");
}
int size = Unsafe.SizeOf<T>() + sizeof(int) * 3;
byte* buffer = stackalloc byte[size];
fixed (char* cLeft = Unsafe.As<string>(left))
fixed (char* cRight = Unsafe.As<string>(right))
{
const int three = 4;
void* leftStart = ((int*)cLeft) - three;
void* rightStart = ((int*)cRight) - three;
var usize = (uint)size;
Unsafe.CopyBlock(buffer, leftStart, usize);
Unsafe.CopyBlock(leftStart, rightStart, usize);
Unsafe.CopyBlock(rightStart, buffer, usize);
}
}
}
class Person { int i = 1; public override string ToString() => $"Person {i}"; }
class Dog { int i = 2; public override string ToString() => $"Dog {i}"; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment