Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Global Variables C#
Message
From
16/12/2009 07:59:13
 
 
General information
Forum:
ASP.NET
Category:
Coding, syntax and commands
Environment versions
Environment:
C# 3.0
Miscellaneous
Thread ID:
01438724
Message ID:
01439334
Views:
52
>Hi,
>
>I've haven't looked properly at the links you provided but quickly testing your code below shows that the value for ConnString() is assigned on program startup - i.e. before any reference it made to it. That's what I was trying to avoid.
>
Back with vs2010 ...


(1) beforeFieldInit http://msdn.microsoft.com/en-us/library/dd310284.aspx

The just-in-time (JIT) compiler’s inliner has been significantly improved to generate better quality code.
However, changing the inliner has an impact on applications that have classes instantiated with constructors
that use the TypeAttributes.BeforeFieldInit enumeration value.
Static initialization of these types is guaranteed to occur at a time before any of the static fields are accessed,
but not before a static method or instance constructor is invoked.
The exact time when the class constructor is invoked can be different in the .NET Framework version 3.5 and 3.5 SP1.


What I understand is
(a) Static initialization of the field(s) is guaranteed to occur before any static field of the class is accessed
It may be at app startup - but my tests indicate that it does not occur at startup

(b) static initialization of those static fields is NOT guaranteed before a static method or instance constructor is invoked
This is what I thought of - but the tests below will prove me wrong
[ not guaranteed does not mean that it won't ]


When does a class receive the 'beforeFieldInit' attribute ?

It gets that attribute if it does not have a static constructor


test program

(1) The static (inline) constructors are not invoked (NoAccessAtAll) when the class is not 'touched'

(2) Accessing any static field, any static method or instantiating the class invokes the static inline initializers


How is (2) done ? It makes a static constructor when there's none provided - see ildasm
[ when you do have a static constructor - the static inline initializers are merged into your static constructor]


(3) With accessors
In the case of class Four - the accessor is not invoked when the class is instantiated - which was your point

Class Four does not have a dummy static constructor


In short
Static constructors - explicit or inline - fire on first access or when the class is instantiated
A way around that is the use of an accessor


BeforeFieldInit or not - not much difference
namespace BaseTest
{
	
	class test2
	{
		

		//______________________________________________________________________
		public static void Main( string[] args )
		{
			//uncomment any - but only one - method at a time for each run


			//NoAccessAtAll();  // not invoked
			//AccessAnyField(); // invoked
			//InvokeStaticMethod(); // invoked
			//InstanceConstructor(); // invoked

			//FullAccessAnyField(); // invoked
			//FullInvokeStaticMethod(); // invoked

			//var xx = new Three();
			// var xx = Three.xx;


			//var xx = new Four();  // not invoked
			//var yy = Four.InLine;  // invoked
			Terminate();	
		}
		//______________________________________________________________________
		static void NoAccessAtAll()
		{

		}

		//______________________________________________________________________
		static void AccessAnyField() // constructor Invoked
		{
			string pp = StaticTest.AField;
			
		}
		//______________________________________________________________________
		static void InvokeStaticMethod()
		{
			StaticTest.Hello();
		}
		//______________________________________________________________________
		static void InstanceConstructor()
		{
			var tt = new StaticTest();
		}
		//______________________________________________________________________

		static void FullAccessAnyField() // constructor Invoked
		{
			string pp = FullStaticTest.AField;

		}
		//______________________________________________________________________
		static void FullInvokeStaticMethod()
		{
			FullStaticTest.Hello();
		}
		//______________________________________________________________________

		static void Terminate()
		{
			Console.Write("Any key top stop");
			Console.ReadKey();
		}
		//______________________________________________________________________
		//______________________________________________________________________
		//______________________________________________________________________
	}
	//______________________________________________________________________
#if false  // implied static class constructor
	.method private hidebysig specialname rtspecialname static 
        void  .cctor() cil managed
{
  // Code size       21 (0x15)
  .maxstack  8
  IL_0000:  call       string BaseTest.StaticTest::InitName()
  IL_0005:  stsfld     string BaseTest.StaticTest::Name
  IL_000a:  ldstr      ""
  IL_000f:  stsfld     string BaseTest.StaticTest::AField
  IL_0014:  ret
} // end of method StaticTest::.cctor
#endif
	//______________________________________________________________________
	class StaticTest
	{
		public static string Name = InitName();
		public static string AField = "";

		//______________________________________________________________________
		static string InitName()
		{
			Console.WriteLine("Static Constructor InitName Invoked");
			return "MyName";
		}
		//______________________________________________________________________
		public static string Hello()
		{
			return "Hello";
		}
	}

	//______________________________________________________________________
	static class FullStaticTest
	{
		public static string Name = InitName();
		public static string AField = "";

		//______________________________________________________________________
		static string InitName()
		{
			Console.WriteLine("Static Constructor InitName Invoked");
			return "MyName";
		}
		//______________________________________________________________________
		public static string Hello()
		{
			return "Hello";
		}
	}
	//______________________________________________________________________
	static class NoFields
	{
		static string xx;

		public static string Hello()
		{
			return "Hello";
		}
	}
	//______________________________________________________________________
	//______________________________________________________________________
	class Three
	{
		public static string xx;

		static Three()
		{
			xx = "xx";
			Console.WriteLine("Static Constructor Three Invoked");
		}

	}
	//______________________________________________________________________
	class Four
	{
		private static string _InLine;

		public static string InLine
		{
			get
			{
				if (_InLine == null)
				{
					Console.WriteLine("Static Constructor Four Inline Invoked");
					_InLine = "xxx";
				}
				return _InLine;

			}
			
		}
	}

	//______________________________________________________________________
}
Gregory
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform