2

I have a static class that has only static properties and a static constructor. When I try to access or set the value of property (with a backing field) the static constructor is not called. However, if I define a static method and try to call it the constructor is executed.

I believe properties are just syntactical sugar and are internally translated as methods. So why does the runtime treats them differently? My class define is given below:

Edit: I have removed the code where I was initializing the value of _fileEncodingText inline.

Edit: The constructor is called but the property is not set. This is probably because "a static constructor runs exactly zero or one times, and runs before a static method call or instance creation in its type". Igor Ostrovsky and Eric Lippert have explained it in their blogs

  1. http://blogs.msdn.com/b/pfxteam/archive/2011/05/03/10159682.aspx
  2. http://ericlippert.com/2013/01/31/the-no-lock-deadlock/

    internal static class AppSettings { static AppSettings() { FileEncodingText = "UTF8"; }

    private static string _fileEncodingText; public static string FileEncodingText { get { return _fileEncodingText; } set { string oldValue = _fileEncodingText; _fileEncodingText = value; try { FileEncoding = Encoding.GetEncoding(value); } catch (System.Exception) { _fileEncodingText = oldValue; FileEncoding = Encoding.UTF8; } } } public static Encoding FileEncoding { get; private set; } 

    }

14
  • Have you got a usage example? Commented Feb 29, 2016 at 11:38
  • 1
    csharpindepth.com/Articles/General/Beforefieldinit.aspx Commented Feb 29, 2016 at 11:39
  • The constructor is called when you set a property Commented Feb 29, 2016 at 11:40
  • Since the class is static, I don't see the point of having the static constructor. Especially since you're already assigning "UTF8" to the class variable anyway. You would normally use a static constructor in a non-static class. Commented Feb 29, 2016 at 11:44
  • Properties are definitely not "just syntactical sugar", they're well recognized by the CLR as properties and not as methods. Commented Feb 29, 2016 at 11:49

3 Answers 3

3

When I try to access or set the value of property (with a backing field) the static constructor is not called.

I'm unable to replicate the issue you're seeing and the above doesn't appear to be happening on my example (see the .NET Fiddle link - https://dotnetfiddle.net/ikIhw3).

It appears that an exception is being thrown when setting the FileEncodingText property which sets the _fileEncodingText backing field back to UTF8. Could this be the cause of what you're seeing?

The following (taken from the aforementioned .NET Fiddle):

internal static class AppSettings { static AppSettings() { Console.WriteLine("In constructor"); FileEncodingText = "UTF8"; } private static string _fileEncodingText = "UTF8"; public static string FileEncodingText { get { return _fileEncodingText; } set { Console.WriteLine("Setting value: " + value); string oldValue = _fileEncodingText; _fileEncodingText = value; try { FileEncoding = Encoding.GetEncoding(value); } catch (System.Exception) { Console.WriteLine("Exception"); _fileEncodingText = oldValue; FileEncoding = Encoding.UTF8; } } } public static Encoding FileEncoding { get; private set; } } public class Program { public static void Main() { AppSettings.FileEncodingText = "UTF16"; Console.WriteLine(AppSettings.FileEncodingText); } } 

Results in the following output:

In constructor Setting value: UTF8 Exception Setting value: UTF16 Exception UTF8 

Updated:

Drilling down into the exception even further, this is the output I'm seeing in the fiddle. Perhaps it's worth adding some logging to see if the exception is being thrown on your end?

Run-time exception (line 45): The type initializer for 'AppSettings' threw an exception. Stack Trace: [System.ArgumentException: 'UTF8' is not a supported encoding name. Parameter name: name] at AppSettings.set_FileEncodingText(String value): line 34 at AppSettings..cctor(): line 9 [System.TypeInitializationException: The type initializer for 'AppSettings' threw an exception.] at Program.Main(): line 45 

As you can see, this is being thrown within the constructor when setting the default UTF8 value?

Sign up to request clarification or add additional context in comments.

6 Comments

I don't get any exception. I am debugging this code in visual studio and the application runs without any issue. I have set a breakpoint in the constructor but the breakpoint is not hit.
That's odd. It's definitely throwing an exception in the fiddle provided in the link. Have you tried setting the FileEncoding property to something out of the ordinary within the catch block and verified it's not changed after the property has returned its value?
Yes.. if I set it to some invalid value, say "Ansi", it throws an exception and the encoding is set to the default value UTF8. In case, I set it to some valid value, say windows-1252, it works with any issue.
Oh ok, that answers that questions then.
I've just updated my answer in include the exception that's being thrown. It appears to be related to the default UTF8 value being set within the constructor.
|
3

I cannot reproduce the issue.

The following program prints

AppSettings - Static constructor called. UTF8 

as expected.

Therefore the answer would appear to be that you have made a mistake somewhere in your testing.

using System; using System.Text; namespace Demo { internal static class AppSettings { static AppSettings() { FileEncodingText = "UTF8"; Console.WriteLine("AppSettings - Static constructor called."); } private static string _fileEncodingText = "UTF8"; public static string FileEncodingText { get { return _fileEncodingText; } set { string oldValue = _fileEncodingText; _fileEncodingText = value; try { FileEncoding = Encoding.GetEncoding(value); } catch (System.Exception) { _fileEncodingText = oldValue; FileEncoding = Encoding.UTF8; } } } public static Encoding FileEncoding { get; private set; } } class Program { static void Main() { Console.WriteLine(AppSettings.FileEncodingText); } } } 

4 Comments

I have a winform application and the code in the constructor is not called.
@Sandeep It won't make any difference whether it's a winform app or not. You must be overlooking something somewhere.
You are write.. the static constructor executes.. but the call to the property doesn't work.
@Sandeep Then I would suspect that an exception is being thrown.
1

according to MSDN documentation

A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.

note that the documentation said "static members" so there is no difference between "Static Property" and "Static Method" [in your case]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.