Question
In an ASP.NET MVC model, what does the { get; set; } syntax mean in this C# class?
public class Genre
{
public string Name { get; set; }
}
How does it work, and why is it written instead of declaring a normal field?
Short Answer
By the end of this page, you will understand C# properties, the roles of get and set, and why public string Name { get; set; } is called an auto-implemented property. You will also know when to use a property, a field, a read-only property, and validation inside a setter.
Concept
Name is a property of the Genre class.
public string Name { get; set; }
It declares a public value named Name whose type is string.
getlets other code read the value.setlets other code assign or change the value.
For example:
var genre = new Genre();
genre.Name = "Science Fiction"; // Uses set
Console.WriteLine(genre.Name); // Uses get
Because the property contains only get; set; with no custom code, it is an auto-implemented property. The C# compiler creates a hidden storage field behind the scenes and connects the get and set accessors to it.
Properties matter because they provide controlled access to an object's data. Today, a property can simply store a value. Later, you can add validation, formatting, logging, or access restrictions without necessarily changing code that uses genre.Name.
Mental Model
Think of an object as a cabinet and its data as items inside it.
A field is like leaving an item directly on an open shelf. A property is like using a labeled drawer:
- The
getaccessor is the rule for taking a look inside the drawer. - The
setaccessor is the rule for putting something into the drawer.
An auto-property gives you a standard drawer with ordinary read and write access:
public string Name { get; set; }
Later, you can change the drawer's rules—for example, refuse an empty name—while users of the class still write genre.Name = "Drama".
Syntax and Examples
The general property syntax is:
accessModifier Type PropertyName
{
get;
set;
}
An auto-implemented property:
public class Genre
{
public string Name { get; set; }
}
Using it:
var genre = new Genre();
genre.Name = "Comedy";
string selectedGenre = genre.Name;
Console.WriteLine(selectedGenre); // Comedy
genre.Name = "Comedy" calls the property's set accessor. Reading genre.Name calls its get accessor.
Equivalent expanded version
The auto-property is conceptually similar to this longer code:
public class Genre
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
}
The compiler-generated backing field is not normally accessible directly. In new code, prefer the short auto-property unless you need custom behavior.
Step by Step Execution
Consider this program:
var genre = new Genre();
genre.Name = "Horror";
string label = genre.Name;
Console.WriteLine(label);
Execution happens in this order:
new Genre()creates aGenreobject. ItsNameproperty has its default value, which isnullfor a normalstringreference.genre.Name = "Horror"invokesName'ssetaccessor. The value"Horror"is stored in the property's hidden backing field.genre.Nameon the right side ofstring label = ...invokes thegetaccessor.- The getter returns
"Horror". labelreceives that value.Console.WriteLine(label)printsHorror.
For an auto-property, the getter and setter are simple reads and writes. A custom property can do extra work in either accessor.
Real World Use Cases
Properties are used throughout C# applications to describe data and expose object state.
- ASP.NET MVC models: A
Genremodel can exposeNameso MVC can bind form input and display it in a view. - Entity Framework models: Properties often represent database columns, such as
Title,Price, orCreatedAt. - API request and response DTOs: JSON serializers commonly read and write public properties.
- Configuration objects: Properties hold settings such as
ConnectionStringorEnableCaching. - Domain objects: A property can prevent invalid values, such as a negative price or blank product name.
Example model used by a form:
public class CreateGenreRequest
{
public string Name { get; set; } = string.Empty;
}
When a user submits a Name value, ASP.NET can populate this public writable property during model binding.
Real Codebase Usage
In production code, properties commonly express who is allowed to read or modify a value.
Public read and write
Useful for simple model or request data:
public string Name { get; set; } = string.Empty;
Public read, restricted write
Useful when a value should only change inside the class:
public decimal Balance { get; private set; }
public void Deposit(decimal amount)
{
if (amount <= 0)
{
throw new ArgumentOutOfRangeException(nameof(amount));
}
Balance += amount;
}
Other code can read Balance, but only BankAccount can set it.
Read-only after construction
Useful for values that identify an object:
public Guid Id { get; init; } = Guid.NewGuid();
init allows assignment during object creation but not ordinary reassignment later.
Validation with a backing field
Use a custom setter when a simple auto-property is not enough:
private string _name = string.Empty;
public string Name
{
get => _name;
set
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("A genre name is required.", nameof(value));
}
_name = value.Trim();
}
}
A common pattern is to keep properties simple for plain data-transfer models and put important business rules in methods or carefully designed setters.
Common Mistakes
Confusing a property with a field
This is a public field, not a property:
public string Name;
This is a property:
public string Name { get; set; }
Properties can later add logic without changing the calling syntax.
Thinking get and set are method calls you write manually
You usually use assignment and reading syntax:
genre.Name = "Drama"; // set
a = genre.Name; // get
Do not try to call genre.set(...) or genre.get().
Using a property as though it were a method
This is incorrect:
var name = genre.Name();
A property is accessed without parentheses:
var name = genre.Name;
Forgetting that string can be null
With nullable reference types enabled, this may produce a warning because Name is not initialized:
public string Name { get; set; }
For a value that starts empty, initialize it:
public string Name { get; set; } = string.Empty;
Alternatively, use string? only when null is a valid and expected value:
public string? Description { get; set; }
Adding validation to an auto-property directly
This is not valid because an auto-property has no explicit backing field to control:
public string Name
{
get;
set
{
// validation attempt
}
}
Use a backing field and a full property when the setter needs logic.
Comparisons
| Declaration | Can read? | Can write? | Typical use |
|---|---|---|---|
public string Name; | Yes | Yes | Simple fields; less common for public object data |
public string Name { get; set; } | Yes | Yes | General-purpose model property |
public string Name { get; private set; } | Yes | Only inside the class | Controlled state changes |
public string Name { get; } | Yes | No after construction | Immutable/read-only values |
public string Name { get; init; } | Yes | Only during initialization | Immutable-style models |
get; set; versus a full property
Use an auto-property when storing a value needs no extra logic:
public int Year { get; set; }
Use a full property when reading or writing must perform work:
private int _year;
public int Year
{
get => _year;
set => _year = Math.Max(0, value);
}
set versus init
setallows reassignment at any time, subject to access modifiers.initallows assignment while an object is being created, then prevents normal reassignment.
var genre = new GenreInfo { Name = "Fantasy" };
// genre.Name = "Mystery"; // Not allowed if Name uses init
Cheat Sheet
// Read and write
public string Name { get; set; } = string.Empty;
// Read publicly; write only inside this class
public string Name { get; private set; } = string.Empty;
// Read-only property
public string Name { get; }
// Set only when constructing the object
public string Name { get; init; } = string.Empty;
- A property exposes data through accessors.
getreturns the value when code reads the property.setreceivesvaluewhen code assigns the property.{ get; set; }is an auto-implemented property: C# creates hidden storage.- Read a property with
object.Property. - Write a property with
object.Property = newValue. - Use a backing field and a full property for validation or transformations.
- Initialize non-nullable
stringproperties, for example with= string.Empty;, when appropriate.
FAQ
What does { get; set; } mean in C#?
It declares a property that can be read (get) and assigned (set). With no accessor bodies, C# automatically creates hidden storage for its value.
Is Name a variable or a method?
Name is a property. It is accessed similarly to a variable, but it can run code through its getter or setter.
Why use a property instead of public string Name;?
A property provides encapsulation. You can later add validation, restrict writes, or change implementation details while preserving usage such as genre.Name.
Does get; set; create a field?
It causes the compiler to create a hidden backing field for an auto-implemented property. You should normally interact with the property, not that generated field.
Can I make a property read-only?
Yes. Use a getter without a public setter:
public string Name { get; }
You can assign it in a constructor.
What is the value keyword in a setter?
In a custom set accessor, value is the value being assigned:
set { _name = value; }
Should ASP.NET MVC models use public setters?
Often yes, especially for models populated by model binding. For domain entities with important rules, consider private set and explicit methods so state changes are controlled.
Should Name be initialized to string.Empty?
Usually, when nullable reference types are enabled and an empty string is an acceptable initial value. Use string? instead if null has a meaningful purpose.
Mini Project
Description
Create a small Genre model that protects its name from invalid input. This demonstrates why a property can begin as { get; set; } and later become a full property with validation without changing how callers read genre.Name.
Goal
Build a Genre class that stores a trimmed, non-empty genre name and prevents invalid names.
Requirements
Use a Genre class with a public Name property.
Reject names that are null, empty, or whitespace-only.
Remove leading and trailing spaces before storing a valid name.
Create one valid genre and print its name.
Demonstrate handling an invalid name without ending the program.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
Best Way to Repeat a Character in C#: Building Repeated Strings Efficiently
Learn the best way to repeat a character in C#, compare StringBuilder, string concatenation, and simpler built-in options.
C# Access Modifiers and static: public, private, protected, and Defaults
Learn how C# public, private, protected, and default access control visibility, and how static differs from instance members.