Skip to content

Commit 2924209

Browse files
CopilotBillWagner
andauthored
Add concrete examples to semantic versioning documentation for beginners (#47092)
* Initial plan * Add concrete examples to semantic versioning section Co-authored-by: BillWagner <[email protected]> * Address review feedback: fix heading styles and reorder optional parameters example Co-authored-by: BillWagner <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: BillWagner <[email protected]>
1 parent fc05938 commit 2924209

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed

docs/csharp/versioning.md

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,138 @@ The most basic approach to SemVer is the 3 component format `MAJOR.MINOR.PATCH`,
3232
- `MINOR` is incremented when you add functionality in a backwards-compatible manner
3333
- `PATCH` is incremented when you make backwards-compatible bug fixes
3434

35+
#### Understand version increments with examples
36+
37+
To help clarify when to increment each version number, here are concrete examples:
38+
39+
### MAJOR version increments (incompatible API changes)
40+
41+
These changes require users to modify their code to work with the new version:
42+
43+
- Removing a public method or property:
44+
45+
```csharp
46+
// Version 1.0.0
47+
public class Calculator
48+
{
49+
public int Add(int a, int b) => a + b;
50+
public int Subtract(int a, int b) => a - b; // This method exists
51+
}
52+
53+
// Version 2.0.0 - MAJOR increment required
54+
public class Calculator
55+
{
56+
public int Add(int a, int b) => a + b;
57+
// Subtract method removed - breaking change!
58+
}
59+
```
60+
61+
- Changing method signatures:
62+
63+
```csharp
64+
// Version 1.0.0
65+
public void SaveFile(string filename) { }
66+
67+
// Version 2.0.0 - MAJOR increment required
68+
public void SaveFile(string filename, bool overwrite) { } // Added required parameter
69+
```
70+
71+
- Changing the behavior of existing methods in ways that break expectations:
72+
73+
```csharp
74+
// Version 1.0.0 - returns null when file not found
75+
public string ReadFile(string path) => File.Exists(path) ? File.ReadAllText(path) : null;
76+
77+
// Version 2.0.0 - MAJOR increment required
78+
public string ReadFile(string path) => File.ReadAllText(path); // Now throws exception when file not found
79+
```
80+
81+
### MINOR version increments (backwards-compatible functionality)
82+
83+
These changes add new features without breaking existing code:
84+
85+
- Adding new public methods or properties:
86+
87+
```csharp
88+
// Version 1.0.0
89+
public class Calculator
90+
{
91+
public int Add(int a, int b) => a + b;
92+
}
93+
94+
// Version 1.1.0 - MINOR increment
95+
public class Calculator
96+
{
97+
public int Add(int a, int b) => a + b;
98+
public int Multiply(int a, int b) => a * b; // New method added
99+
}
100+
```
101+
102+
- Adding new overloads:
103+
104+
```csharp
105+
// Version 1.0.0
106+
public void Log(string message) { }
107+
108+
// Version 1.1.0 - MINOR increment
109+
public void Log(string message) { } // Original method unchanged
110+
public void Log(string message, LogLevel level) { } // New overload added
111+
```
112+
113+
- Adding optional parameters to existing methods:
114+
115+
```csharp
116+
// Version 1.0.0
117+
public void SaveFile(string filename) { }
118+
119+
// Version 1.1.0 - MINOR increment
120+
public void SaveFile(string filename, bool overwrite = false) { } // Optional parameter
121+
```
122+
123+
> [!NOTE]
124+
> This is a *source compatible change*, but a *binary breaking change*. Users of this library must recompile for it to work correctly. Many libraries would consider this only in *major* version changes, not *minor* version changes.
125+
126+
### PATCH version increments (backwards-compatible bug fixes)
127+
128+
These changes fix issues without adding new features or breaking existing functionality:
129+
130+
- Fixing a bug in an existing method's implementation:
131+
132+
```csharp
133+
// Version 1.0.0 - has a bug
134+
public int Divide(int a, int b)
135+
{
136+
return a / b; // Bug: doesn't handle division by zero
137+
}
138+
139+
// Version 1.0.1 - PATCH increment
140+
public int Divide(int a, int b)
141+
{
142+
if (b == 0) throw new ArgumentException("Cannot divide by zero");
143+
return a / b; // Bug fixed, behavior improved but API unchanged
144+
}
145+
```
146+
147+
- Performance improvements that don't change the API:
148+
149+
```csharp
150+
// Version 1.0.0
151+
public List<int> SortNumbers(List<int> numbers)
152+
{
153+
return numbers.OrderBy(x => x).ToList(); // Slower implementation
154+
}
155+
156+
// Version 1.0.1 - PATCH increment
157+
public List<int> SortNumbers(List<int> numbers)
158+
{
159+
var result = new List<int>(numbers);
160+
result.Sort(); // Faster implementation, same API
161+
return result;
162+
}
163+
```
164+
165+
The key principle is: if existing code can use your new version without any changes, it's a MINOR or PATCH update. If existing code needs to be modified to work with your new version, it's a MAJOR update.
166+
35167
There are also ways to specify other scenarios, for example, pre-release versions, when applying version information to your .NET library.
36168

37169
### Backwards Compatibility

0 commit comments

Comments
 (0)