diff --git a/docs/csharp/misc/cs0236.md b/docs/csharp/misc/cs0236.md index 3d7f519d4d605..64d9cc037c644 100644 --- a/docs/csharp/misc/cs0236.md +++ b/docs/csharp/misc/cs0236.md @@ -13,9 +13,27 @@ A field initializer cannot reference the non-static field, method, or property ' Instance fields cannot be used to initialize other instance fields outside a method. +## Why this error occurs + +The compiler enforces this restriction because of how object initialization works in C#. When an object is created, field initializers are processed before any constructor code runs. During this phase: + +1. **Field dependency restriction**: While field initializers are processed in lexical order within a single file, the rule prevents dependencies between fields to allow class authors to rearrange fields without introducing compiler errors. For partial classes, the order of field initializers across different source files isn't specified. + +2. **Object is not fully constructed**: When field initializers run, the object instance is in an incomplete state. Allowing references between fields during this phase could lead to accessing uninitialized memory or unpredictable behavior. + +3. **Compiler safety**: This restriction prevents potential runtime errors and ensures predictable object construction behavior. + +The compiler detects this pattern during compilation and reports CS0236 to prevent these potential issues. + ## To correct this error -If you are trying to initialize a variable outside a method, consider performing the initialization inside the class constructor. For more information, see [Methods](../programming-guide/classes-and-structs/methods.md). +1. **Move initialization to constructor**: Perform the initialization inside the class constructor where all fields are guaranteed to be available. + +2. **Use static fields**: If the referenced field doesn't need to be instance-specific, consider making it static. + +3. **Use default values**: Initialize fields with literal values or expressions that don't reference other instance members. + +4. **Lazy initialization**: Use properties with backing fields for complex initialization logic that depends on other instance members. ## Example @@ -26,13 +44,47 @@ public class MyClass { public int i = 5; - // To fix the error, remove "= i", and uncomment the line in constructor. + // CS0236: Field initializer cannot reference instance field 'i' + // This restriction allows class authors to rearrange fields without compiler errors public int j = i; // CS0236 public MyClass() { - // Uncomment the following. - //j = i; + // This works because both fields are guaranteed to be initialized + // before constructor code runs + j = i; + } +} +``` + +## Additional examples + +The following examples demonstrate different scenarios where CS0236 occurs: + +```csharp +public class Examples +{ + private string name = "Default"; + + // CS0236: Cannot reference instance field in initializer + private string displayName = name.ToUpper(); + + // CS0236: Cannot reference instance method in initializer + private int length = GetNameLength(); + + // CS0236: Cannot reference instance property in initializer + private string formatted = FormattedName; + + public string FormattedName => $"Name: {name}"; + + private int GetNameLength() => name.Length; + + public Examples() + { + // All of these work in the constructor: + displayName = name.ToUpper(); + length = GetNameLength(); + formatted = FormattedName; } } ```