I read the book "CLR via C#" by Jeffrey Richter. In chapter 20, there is a code example demonstrating usage of Constrained Execution Regions (CERs):
private static void Demo2() {
// Force the code in the finally to be eagerly prepared
RuntimeHelpers.PrepareConstrainedRegions(); // System.Runtime.CompilerServices namespace
try {
Console.WriteLine("In try");
}
finally {
// Type2’s static constructor is implicitly called in here
Type2.M();
}
}
public class Type2 {
static Type2() {
Console.WriteLine("Type2's static ctor called");
}
// Use this attribute defined in the System.Runtime.ConstrainedExecution namespace
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static void M() { }
}
And the following text:
Now, when I run this version of the code, I get the following output.
Type2's static ctor called In try
But when I run this code I get the following output no matter if I use CERs or not:
In try
Type2's static ctor called
So, Type2
constructor is getting called after try
block (breaking the meaning of CERs usages, as I understand it).
What can be possible reason of this?
EDIT: I'm using .Net Core 3.1 and VS Enterprise 2019 Preview Version 16.6.0 Preview 3.0, my code is:
using System;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
public sealed class Program
{
public static void Main()
{
Demo2();
}
private static void Demo2()
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
Console.WriteLine("In try");
}
finally
{
Type2.M();
}
}
}
public class Type2
{
static Type2()
{
Console.WriteLine("Type2's static ctor called");
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static void M() { }
}
By the way, Type2
class can be inside the Program
, it does not change the output.
Here is a quote from Microsoft's article about Constrained Execution Regions: