Skip to content

Instantly share code, notes, and snippets.

@yutopio
Created December 2, 2016 01:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yutopio/697ac1f75b66fca2b16ceedb9b0c1dd5 to your computer and use it in GitHub Desktop.
Save yutopio/697ac1f75b66fca2b16ceedb9b0c1dd5 to your computer and use it in GitHub Desktop.
using System;
using System.Runtime.CompilerServices;
using static System.Console;
// No effect...
//[CompilationRelaxations(CompilationRelaxations.NoStringInterning)]
class Program
{
const string kHello = "HelloWorld";
class HelloWorld { }
static void Main(string[] args)
{
var myStr = "HelloWorld";
string x, y;
AreEqual(myStr, kHello);
AreEqual(myStr, ConstFunc());
AreEqual(myStr, ConstAndConst());
AreEqual(myStr, NameOf());
AreEqual(myStr, x = ConstAndToString());
AreEqual(myStr, y = string.Intern(x)); // Should be False after Ngen
AreEqual(myStr, x = string.Format(myStr));
AreEqual(myStr, y = string.Intern(x)); // Should be False after Ngen
// Advanced: Inspect in the watch pane. They should have the same value,
// which points to the physical location of the interned literal.
//
// *(void**)&myStr
// *(void**)&y
//
// Then open the memory pane (Ctrl+Alt+M, 1) and go to the given address.
// String manipulation after the instance creation.
x = new string(' ', myStr.Length);
unsafe
{
fixed (char* pSrc = myStr)
fixed (char* pDst = x)
{
var bytes = myStr.Length * sizeof(char);
Buffer.MemoryCopy(pSrc, pDst, bytes, bytes);
}
}
WriteLine(x);
AreEqual(myStr, x);
AreEqual(myStr, string.Intern(x));
unsafe
{
fixed (char* pt = myStr)
pt[0] = '@';
}
WriteLine(kHello); // Attention please! Constant is changed.
// Modify the length to cause buffer overrun.
unsafe
{
fixed (char* pt = myStr)
((int*)pt)[-1] = 100;
}
WriteLine(kHello);
}
static string ConstFunc() => "HelloWorld";
static string ConstAndConst() => "Hello" + "World";
static string ConstAndToString() => "Hello" + "World".ToString();
static string NameOf() => nameof(HelloWorld);
static void AreEqual(string s1, string s2) =>
WriteLine(ReferenceEquals(s1, s2));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment