Skip to content

How to Resolve Error "CS0840: Property must declare a body because it is not marked abstract or extern" in C#

Fix the CS0840 compiler error in C# by ensuring properties are either fully auto-implemented, manually implemented with both get/set, or marked abstract.

The Compiler Error CS0840 is a syntax error regarding Properties. The message reads: "'PropertyName' must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors."

In C#, a property can be implemented in two main ways:

  1. Auto-Implemented: { get; set; } (The compiler creates the storage field for you).
  2. Manually Implemented: { get { return ... } set { ... } } (You write the logic).

CS0840 occurs when you try to create a "Hybrid" property (manually implementing one accessor but trying to auto-implement the other), or when you define a property that looks like an abstract declaration inside a non-abstract class.

Understanding Property Syntax

To satisfy the compiler, a property must fall into one of these strict categories:

  • Full Auto-Property: Both accessors have semicolons.
    • public int X { get; set; }
  • Full Manual Property: Both accessors have bodies.
    • public int X { get { return 0; } set { } }
  • Abstract Property: No bodies, marked abstract.
    • public abstract int X { get; set; }

You cannot mix and match styles within a single property.

Scenario 1: Mixing Manual and Auto Accessors (The Hybrid Error)

This is the most common cause in modern C#. You want custom logic for the get accessor (to calculate a value), but you want the set accessor to just store the value automatically. C# does not support this partial automation. If you define a body for one, you must define a body for the other.

Example of error

Attempting to manually implement get while using auto-syntax for set.

public class User
{
    private string _name;

    // ⛔️ Error CS0840: 'Name' must declare a body because it is not marked abstract or extern.
    // You defined a body for 'get', so 'set' cannot be auto-implemented with ';'.
    public string Name
    {
        get { return _name ?? "Unknown"; }
        set; 
    }
}

Solution: Use a Backing Field

You must manually implement the setter and store the value in a private backing field.

public class User
{
    private string _name;

    public string Name
    {
        // ✅ Correct: Both accessors are manually implemented.
        get { return _name ?? "Unknown"; }
        set { _name = value; }
    }
}

Scenario 2: Intending to make an Abstract Property

Sometimes you declare a property using the short syntax { get; set; } intending for derived classes to implement it, but you forget to mark the property (or the class) as abstract. While { get; set; } is valid as an auto-property, if you use { get; } (read-only) without initializing it, or in older versions of C#, the compiler might interpret this as an incomplete definition.

More specifically, if you mistakenly use the extern syntax style without the keyword, this error appears.

Example of error

Defining a property that looks like a contract (interface style) inside a standard class.

public class BaseEntity
{
    // ⛔️ Error CS0840: The compiler thinks you want an auto-prop, 
    // but in some contexts (or if you wanted it abstract), this is ambiguous.
    // If you wanted this to be abstract, you forgot the keyword.
    public int Id { get; set; } 
    
    // Note: In modern C#, { get; set; } is valid as an auto-prop. 
    // But if you meant "I will define this elsewhere", you need abstract.
}

Solution: Add abstract

If the class is meant to be a base class and holds no data itself, mark it abstract.

// ✅ Correct: The class is abstract
public abstract class BaseEntity
{
    // ✅ Correct: The property is abstract.
    // This tells the compiler: "No body needed here, children will provide it."
    public abstract int Id { get; set; }
}

Scenario 3: Legacy C# Versions (Read-Only Auto-Props)

If you are working on a very old project (using C# 5.0 or earlier, targeted at .NET Framework 4.5 or older), Read-Only Auto-Properties ({ get; }) were not yet supported.

Example of error (In C# 5.0)

public class Config
{
    // ⛔️ Error CS0840 (Only in old compilers): 
    // Auto-implemented properties must define both get and set accessors.
    public int MaxUsers { get; }
}

Solution: Private Set

In older versions, you must provide a private set to satisfy the syntax requirement.

public class Config
{
    // ✅ Correct (Legacy Compatible): Add a private setter.
    public int MaxUsers { get; private set; }

    public Config()
    {
        MaxUsers = 100;
    }
}

Conclusion

CS0840 ensures you don't write "half-properties."

  1. Check Consistency: If you write { get { ... } ... }, you must write { set { ... } }. You cannot mix manual logic with auto-properties ;.
  2. Check Abstract: If you don't want to write a body at all, ensure the property is marked abstract.
  3. Check Version: If using { get; } read-only properties, ensure you are using C# 6.0 or newer.
Navigation