Skip to content

Add concrete examples to semantic versioning documentation for beginners #47092

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions docs/csharp/versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,135 @@ The most basic approach to SemVer is the 3 component format `MAJOR.MINOR.PATCH`,
- `MINOR` is incremented when you add functionality in a backwards-compatible manner
- `PATCH` is incremented when you make backwards-compatible bug fixes

#### Understanding version increments with examples

To help clarify when to increment each version number, here are concrete examples:

**MAJOR version increments (incompatible API changes):**

These changes require users to modify their code to work with the new version:

- Removing a public method or property:

```csharp
// Version 1.0.0
public class Calculator
{
public int Add(int a, int b) => a + b;
public int Subtract(int a, int b) => a - b; // This method exists
}

// Version 2.0.0 - MAJOR increment required
public class Calculator
{
public int Add(int a, int b) => a + b;
// Subtract method removed - breaking change!
}
```

- Changing method signatures:

```csharp
// Version 1.0.0
public void SaveFile(string filename) { }

// Version 2.0.0 - MAJOR increment required
public void SaveFile(string filename, bool overwrite) { } // Added required parameter
```

- Changing the behavior of existing methods in ways that break expectations:

```csharp
// Version 1.0.0 - returns null when file not found
public string ReadFile(string path) => File.Exists(path) ? File.ReadAllText(path) : null;

// Version 2.0.0 - MAJOR increment required
public string ReadFile(string path) => File.ReadAllText(path); // Now throws exception when file not found
```

**MINOR version increments (backwards-compatible functionality):**

These changes add new features without breaking existing code:

- Adding new public methods or properties:

```csharp
// Version 1.0.0
public class Calculator
{
public int Add(int a, int b) => a + b;
}

// Version 1.1.0 - MINOR increment
public class Calculator
{
public int Add(int a, int b) => a + b;
public int Multiply(int a, int b) => a * b; // New method added
}
```

- Adding optional parameters to existing methods:

```csharp
// Version 1.0.0
public void SaveFile(string filename) { }

// Version 1.1.0 - MINOR increment
public void SaveFile(string filename, bool overwrite = false) { } // Optional parameter
```

- Adding new overloads:

```csharp
// Version 1.0.0
public void Log(string message) { }

// Version 1.1.0 - MINOR increment
public void Log(string message) { } // Original method unchanged
public void Log(string message, LogLevel level) { } // New overload added
```

**PATCH version increments (backwards-compatible bug fixes):**

These changes fix issues without adding new features or breaking existing functionality:

- Fixing a bug in an existing method's implementation:

```csharp
// Version 1.0.0 - has a bug
public int Divide(int a, int b)
{
return a / b; // Bug: doesn't handle division by zero
}

// Version 1.0.1 - PATCH increment
public int Divide(int a, int b)
{
if (b == 0) throw new ArgumentException("Cannot divide by zero");
return a / b; // Bug fixed, behavior improved but API unchanged
}
```

- Performance improvements that don't change the API:

```csharp
// Version 1.0.0
public List<int> SortNumbers(List<int> numbers)
{
return numbers.OrderBy(x => x).ToList(); // Slower implementation
}

// Version 1.0.1 - PATCH increment
public List<int> SortNumbers(List<int> numbers)
{
var result = new List<int>(numbers);
result.Sort(); // Faster implementation, same API
return result;
}
```

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.

There are also ways to specify other scenarios, for example, pre-release versions, when applying version information to your .NET library.

### Backwards Compatibility
Expand Down
Loading