A field initializer cannot reference a non-static field, method, or property

I have a class, and when I try to use it in another class, I get the error below.

using System; using System.Collections.Generic; using System.Linq; namespace MySite { public class Reminders { public Dictionary<TimeSpan, string> TimeSpanText { get; set; } // We are setting the default values using the Costructor public Reminders() { TimeSpanText.Add(TimeSpan.Zero, "None"); TimeSpanText.Add(new TimeSpan(0, 0, 5, 0), "5 minutes before"); TimeSpanText.Add(new TimeSpan(0, 0, 15, 0), "15 minutes before"); TimeSpanText.Add(new TimeSpan(0, 0, 30, 0), "30 minutes before"); TimeSpanText.Add(new TimeSpan(0, 1, 0, 0), "1 hour before"); TimeSpanText.Add(new TimeSpan(0, 2, 0, 0), "2 hours before"); TimeSpanText.Add(new TimeSpan(1, 0, 0, 0), "1 day before"); TimeSpanText.Add(new TimeSpan(2, 0, 0, 0), "2 day before"); } } } 

Using a class in another class

 class SomeOtherClass { private Reminders reminder = new Reminders(); // error happens on this line: private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; .... 

Error (CS0236):

 A field initializer cannot reference the nonstatic field, method, or property 

Why is this happening and how to fix it?

+77
c #
Jan 21 '13 at 13:01
source share
4 answers

This line:

 private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; 

You cannot use an instance variable to initialize another instance variable. What for? Since the compiler can change them, there is no guarantee that reminder will be initialized to defaultReminder , so the line above may NullReferenceException .

Instead, just use:

 private dynamic defaultReminder = TimeSpan.FromMinutes(15); 

Alternatively, configure the value in the constructor:

 private dynamic defaultReminder; public Reminders() { defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; } 

More details about this compiler error in MSDN - Compiler Error CS0236 .

+114
Jan 21 '13 at 13:02
source share

You need to put this code in the constructor of your class:

 private Reminders reminder = new Reminders(); private dynamic defaultReminder; public YourClass() { defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; } 

The reason is that you cannot use one instance variable to initialize another with a field initializer.

+20
Jan 21 '13 at 13:02
source share

you can use this as

 private dynamic defaultReminder => reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; 
+6
Aug 6 '16 at 16:17
source share

private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; It is the initializer of the field and is executed first (before any field without an initializer is set to its default value, and before the called instance constructor is executed). Instance fields that do not have an initializer will only have a valid (default) value after all instance field initializers have completed. Due to the order of initialization, instance constructors are executed last, so an instance is not created at the moment the initializers are executed. Therefore, the compiler cannot allow references to any property of the instance (or field) before the class instance is fully created. This is because any access to an instance variable, such as reminder , implicitly refers to an instance ( this ) to tell the compiler a specific place in the instance memory to use.

This is also the reason why this not allowed in the instance field initializer.

The variable initializer for the instance field cannot refer to the instance being created. Thus, this is a compile-time error for referencing this in a variable initializer, since it is a compile-time error for a variable initializer for referencing any element of an instance via prime-.

The only type members that are guaranteed to be initialized before executing instance field initializers are class field initializers (static) and class constructors (static) and class methods. Because instances are independently referenced by static elements, they can be referenced at any time:

 class SomeOtherClass { private static Reminders reminder = new Reminders(); // This operation is allowed, // since the compiler can guarantee that the referenced class member is already initialized // when this instance field initializer executes private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; } 

This is why instance field initializers are allowed to refer only to class members (static members). These compiler initialization rules will provide a deterministic type implementation.

For more information, I recommend this document: Microsoft Docs: Class declarations .

This means that an instance field that references another instance element to initialize its value must be initialized from the instance constructor, or the specified element must be declared static .

+1
Sep 02 '19 at 21:23
source share



All Articles