Events
Mar 17, 9 PM - Mar 21, 10 AM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
It's possible to split the definition of a class, a struct, an interface, or a method over two or more source files. Each source file contains a section of the type or method definition, and all parts are combined when the application is compiled.
There are several situations when splitting a class definition is desirable:
To split a class definition, use the partial keyword modifier. In practice, each partial class is typically defined in a separate file, making it easier to manage and expand the class over time.
The following Employee
example demonstrates how the class might be divided across two files: Employee_Part1.cs and Employee_Part2.cs.
// This is in Employee_Part1.cs
public partial class Employee
{
public void DoWork()
{
Console.WriteLine("Employee is working.");
}
}
// This is in Employee_Part2.cs
public partial class Employee
{
public void GoToLunch()
{
Console.WriteLine("Employee is at lunch.");
}
}
//Main program demonstrating the Employee class usage
public class Program
{
public static void Main()
{
Employee emp = new Employee();
emp.DoWork();
emp.GoToLunch();
}
}
// Expected Output:
// Employee is working.
// Employee is at lunch.
The partial
keyword indicates that other parts of the class, struct, or interface can be defined in the namespace. All the parts must use the partial
keyword. All the parts must be available at compile time to form the final type. All the parts must have the same accessibility, such as public
, private
, and so on.
If any part is declared abstract, then the whole type is considered abstract. If any part is declared sealed, then the whole type is considered sealed. If any part declares a base type, then the whole type inherits that class.
All the parts that specify a base class must agree, but parts that omit a base class still inherit the base type. Parts can specify different base interfaces, and the final type implements all the interfaces listed by all the partial declarations. Any class, struct, or interface members declared in a partial definition are available to all the other parts. The final type is the combination of all the parts at compile time.
Note
The partial
modifier is not available on delegate or enumeration declarations.
The following example shows that nested types can be partial, even if the type they're nested within isn't partial itself.
class Container
{
partial class Nested
{
void Test() { }
}
partial class Nested
{
void Test2() { }
}
}
At compile time, attributes of partial-type definitions are merged. For example, consider the following declarations:
[SerializableAttribute]
partial class Moon { }
[ObsoleteAttribute]
partial class Moon { }
They're equivalent to the following declarations:
[SerializableAttribute]
[ObsoleteAttribute]
class Moon { }
The following are merged from all the partial-type definitions:
For example, consider the following declarations:
partial class Earth : Planet, IRotate { }
partial class Earth : IRevolve { }
They're equivalent to the following declarations:
class Earth : Planet, IRotate, IRevolve { }
There are several rules to follow when you're working with partial class definitions:
partial
. For example, the following class declarations generate an error:public partial class A { }
//public class A { } // Error, must also be marked partial
partial
modifier can only appear immediately before the keyword class
, struct
, or interface
.partial class ClassWithNestedClass
{
partial class NestedClass { }
}
partial class ClassWithNestedClass
{
partial class NestedClass { }
}
For more information, see Constraints on Type Parameters.
In the following example, the fields and constructor of the Coords
class are declared in one partial class definition (Coords_Part1.cs
), and the PrintCoords
method is declared in another partial class definition (Coords_Part2.cs
). This separation demonstrates how partial classes can be divided across multiple files for easier maintainability.
// This is in Coords_Part1.cs
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
// This is in Coords_Part2.cs
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
// Main program demonstrating the Coords class usage
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
// Output: Coords: 10,15
The following example shows that you can also develop partial structs and interfaces.
partial interface ITest
{
void Interface_Test();
}
partial interface ITest
{
void Interface_Test2();
}
partial struct S1
{
void Struct_Test() { }
}
partial struct S1
{
void Struct_Test2() { }
}
A partial class or struct can contain a partial member. One part of the class contains the signature of the member. An implementation can be defined in the same part or another part.
An implementation isn't required for a partial method when the signature obeys the following rules:
private
access by default.void
.out
modifier.The method and all calls to the method are removed at compile time when there's no implementation.
Any method that doesn't conform to all those restrictions, including properties and indexers, must provide an implementation. That implementation might be supplied by a source generator. Partial properties can't be implemented using automatically implemented properties. The compiler can't distinguish between an automatically implemented property, and the declaring declaration of a partial property.
Beginning with C# 13, the implementing declaration for a partial property can use field backed properties to define the implementing declaration. A field backed property provides a concise syntax where the field
keyword accesses the compiler synthesized backing field for the property. For example, you could write the following:
// in file1.cs
public partial class PropertyBag
{
// Defining declaration
public partial int MyProperty { get; set; }
}
// In file2.cs
public partial class PropertyBag
{
// Defining declaration
public partial int MyProperty { get => field; set; }
}
You can use field
in either the get
or set
accessor, or both.
Important
The field
keyword is a preview feature in C# 13. You must be using .NET 9 and set your <LangVersion>
element to preview
in your project file in order to use the field
contextual keyword.
You should be careful using the field
keyword feature in a class that has a field named field
. The new field
keyword shadows a field named field
in the scope of a property accessor. You can either change the name of the field
variable, or use the @
token to reference the field
identifier as @field
. You can learn more by reading the feature specification for the field
keyword.
Partial methods enable the implementer of one part of a class to declare a member. The implementer of another part of the class can define that member. There are two scenarios where this separation is useful: templates that generate boilerplate code, and source generators.
// Definition in file1.cs
partial void OnNameChanged();
// Implementation in file2.cs
partial void OnNameChanged()
{
// method body
}
For more information, see Partial types and Partial methods in the C# Language Specification. The language specification is the definitive source for C# syntax and usage. The new features for partial methods are defined in the feature specification.
.NET feedback
.NET is an open source project. Select a link to provide feedback:
Events
Mar 17, 9 PM - Mar 21, 10 AM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowTraining
Module
Manage Class Implementations - Training
Learn how to implement classes using advanced techniques like static classes, partial classes, and object initializers that can improve the readability, maintainability, and organization of your code.
Documentation
sealed modifier - C# reference
sealed modifier - C# Reference
internal keyword - C# reference
internal - C# Reference
All types and type members in C# have an accessibility level that controls whether they can be used from other code. Review this list of access modifiers.