docs(functional): 添加函数式编程类型文档和单元测试

- 新增 Option 类型文档,包含核心类型及扩展方法说明
- 新增 Result 类型文档,包含核心类型及扩展方法说明
- 新增 Nullable Extensions 文档,提供可空类型转换功能说明
- 添加 Option 类型单元测试,覆盖基本功能和扩展方法
- 添加 Result 类型单元测试,验证成功失败结果处理
- 添加 Nullable Extensions 单元测试,确保类型转换正确性
- 添加 Option 和 Result 扩展方法的完整测试用例
- [release ci]
This commit is contained in:
GeWuYou 2026-01-31 21:52:04 +08:00
parent 1b442edadd
commit 3493d6a481
7 changed files with 925 additions and 0 deletions

View File

@ -0,0 +1,78 @@
using GFramework.Core.functional.types;
using NUnit.Framework;
namespace GFramework.Core.Tests.functional.types;
/// <summary>
/// NullableExtensions扩展方法测试类用于验证可空类型转换为Option类型的功能
/// 包括引用类型和值类型的可空转换测试
/// </summary>
[TestFixture]
public class NullableExtensionsTests
{
/// <summary>
/// 测试引用类型可空转换 - 验证非null值转换为Some
/// </summary>
[Test]
public void NullableExtensions_ReferenceType_ToOption_Should_Create_Some_For_NonNull()
{
// Arrange
string? value = "Hello";
// Act
var option = value.ToOption();
// Assert
Assert.That(option.IsSome, Is.True);
Assert.That(option.Value, Is.EqualTo("Hello"));
}
/// <summary>
/// 测试引用类型可空转换 - 验证null值转换为None
/// </summary>
[Test]
public void NullableExtensions_ReferenceType_ToOption_Should_Create_None_For_Null()
{
// Arrange
string? value = null;
// Act
var option = value.ToOption();
// Assert
Assert.That(option.IsNone, Is.True);
}
/// <summary>
/// 测试值类型可空转换 - 验证有值的可空值类型转换为Some
/// </summary>
[Test]
public void NullableExtensions_ValueType_ToOption_Should_Create_Some_For_HasValue()
{
// Arrange
int? value = 42;
// Act
var option = value.ToOption();
// Assert
Assert.That(option.IsSome, Is.True);
Assert.That(option.Value, Is.EqualTo(42));
}
/// <summary>
/// 测试值类型可空转换 - 验证无值的可空值类型转换为None
/// </summary>
[Test]
public void NullableExtensions_ValueType_ToOption_Should_Create_None_For_NoValue()
{
// Arrange
int? value = null;
// Act
var option = value.ToOption();
// Assert
Assert.That(option.IsNone, Is.True);
}
}

View File

@ -0,0 +1,181 @@
using GFramework.Core.functional.types;
using NUnit.Framework;
namespace GFramework.Core.Tests.functional.types;
/// <summary>
/// OptionExtensions扩展方法测试类用于验证Option类型的功能扩展方法
/// 包括映射、绑定、过滤和匹配操作等功能的测试
/// </summary>
[TestFixture]
public class OptionExtensionsTests
{
/// <summary>
/// 测试Map方法 - 验证Some值能正确映射
/// </summary>
[Test]
public void Option_Map_Should_Transform_Some_Value()
{
// Arrange
var option = Option<string>.Some("hello");
// Act
var result = option.Map(s => s.Length);
// Assert
Assert.That(result.IsSome, Is.True);
Assert.That(result.Value, Is.EqualTo(5));
}
/// <summary>
/// 测试Map方法 - 验证None映射后仍为None
/// </summary>
[Test]
public void Option_Map_Should_Return_None_For_None()
{
// Arrange
var option = Option<string>.None();
// Act
var result = option.Map(s => s.Length);
// Assert
Assert.That(result.IsNone, Is.True);
}
/// <summary>
/// 测试Bind方法 - 验证Some值能正确绑定到另一个Option
/// </summary>
[Test]
public void Option_Bind_Should_Transform_Some_To_Another_Option()
{
// Arrange
var option = Option<string>.Some("hello");
// Act
var result = option.Bind(s => s.Length > 3 ? Option<int>.Some(s.Length) : Option<int>.None());
// Assert
Assert.That(result.IsSome, Is.True);
Assert.That(result.Value, Is.EqualTo(5));
}
/// <summary>
/// 测试Bind方法 - 验证None绑定后仍为None
/// </summary>
[Test]
public void Option_Bind_Should_Return_None_For_None()
{
// Arrange
var option = Option<string>.None();
// Act
var result = option.Bind(s => Option<int>.Some(s.Length));
// Assert
Assert.That(result.IsNone, Is.True);
}
/// <summary>
/// 测试Bind方法 - 验证Some值绑定到None的情况
/// </summary>
[Test]
public void Option_Bind_Should_Return_None_When_Binder_Returns_None()
{
// Arrange
var option = Option<string>.Some("hi"); // 长度小于3
// Act
var result = option.Bind(s => s.Length > 3 ? Option<int>.Some(s.Length) : Option<int>.None());
// Assert
Assert.That(result.IsNone, Is.True);
}
/// <summary>
/// 测试Filter方法 - 验证满足条件的Some值保留
/// </summary>
[Test]
public void Option_Filter_Should_Keep_Some_When_Predicate_Matches()
{
// Arrange
var option = Option<string>.Some("hello");
// Act
var result = option.Filter(s => s.Length > 3);
// Assert
Assert.That(result.IsSome, Is.True);
Assert.That(result.Value, Is.EqualTo("hello"));
}
/// <summary>
/// 测试Filter方法 - 验证不满足条件的Some值变为None
/// </summary>
[Test]
public void Option_Filter_Should_Return_None_When_Predicate_Does_Not_Match()
{
// Arrange
var option = Option<string>.Some("hi");
// Act
var result = option.Filter(s => s.Length > 3);
// Assert
Assert.That(result.IsNone, Is.True);
}
/// <summary>
/// 测试Filter方法 - 验证None过滤后仍为None
/// </summary>
[Test]
public void Option_Filter_Should_Return_None_For_None()
{
// Arrange
var option = Option<string>.None();
// Act
var result = option.Filter(s => s.Length > 3);
// Assert
Assert.That(result.IsNone, Is.True);
}
/// <summary>
/// 测试Match方法 - 验证Some值执行some分支
/// </summary>
[Test]
public void Option_Match_Should_Execute_Some_Branch_For_Some()
{
// Arrange
var option = Option<string>.Some("hello");
// Act
var result = option.Match(
some: s => $"Value: {s}",
none: () => "No value"
);
// Assert
Assert.That(result, Is.EqualTo("Value: hello"));
}
/// <summary>
/// 测试Match方法 - 验证None值执行none分支
/// </summary>
[Test]
public void Option_Match_Should_Execute_None_Branch_For_None()
{
// Arrange
var option = Option<string>.None();
// Act
var result = option.Match(
some: s => $"Value: {s}",
none: () => "No value"
);
// Assert
Assert.That(result, Is.EqualTo("No value"));
}
}

View File

@ -0,0 +1,70 @@
using GFramework.Core.functional.types;
using NUnit.Framework;
namespace GFramework.Core.Tests.functional.types;
/// <summary>
/// Option类型测试类用于验证Option类型的基本功能
/// 包括创建Some和None实例、值访问等功能的测试
/// </summary>
[TestFixture]
public class OptionTests
{
/// <summary>
/// 测试创建Some实例 - 验证非null值能正确创建Some
/// </summary>
[Test]
public void Option_Some_Should_Create_WithValue()
{
// Arrange
var value = "Hello";
// Act
var option = Option<string>.Some(value);
// Assert
Assert.That(option.IsSome, Is.True);
Assert.That(option.IsNone, Is.False);
Assert.That(option.Value, Is.EqualTo(value));
}
/// <summary>
/// 测试创建Some实例 - 验证null值时抛出异常
/// </summary>
[Test]
public void Option_Some_Should_Throw_When_Value_Is_Null()
{
// Act & Assert
Assert.Throws<ArgumentNullException>(() => Option<string>.Some(null!));
}
/// <summary>
/// 测试创建None实例 - 验证能正确创建None
/// </summary>
[Test]
public void Option_None_Should_Create_Empty_Instance()
{
// Act
var option = Option<string>.None();
// Assert
Assert.That(option.IsNone, Is.True);
Assert.That(option.IsSome, Is.False);
}
/// <summary>
/// 测试访问None的值 - 验证抛出异常
/// </summary>
[Test]
public void Option_None_Value_Access_Should_Throw_Exception()
{
// Arrange
var option = Option<string>.None();
// Act & Assert
Assert.Throws<InvalidOperationException>(() =>
{
var _ = option.Value;
});
}
}

View File

@ -0,0 +1,141 @@
using GFramework.Core.functional.types;
using NUnit.Framework;
namespace GFramework.Core.Tests.functional.types;
/// <summary>
/// OptionValueExtensions扩展方法测试类用于验证Option类型值的操作扩展方法
/// 包括获取默认值、备选Option等功能的测试
/// </summary>
[TestFixture]
public class OptionValueExtensionsTests
{
/// <summary>
/// 测试GetOrElse方法 - 验证Some值直接返回其值
/// </summary>
[Test]
public void OptionValueExtensions_GetOrElse_Should_Return_Value_For_Some()
{
// Arrange
var option = Option<string>.Some("actual value");
// Act
var result = option.GetOrElse("default value");
// Assert
Assert.That(result, Is.EqualTo("actual value"));
}
/// <summary>
/// 测试GetOrElse方法 - 验证None值返回默认值
/// </summary>
[Test]
public void OptionValueExtensions_GetOrElse_Should_Return_Default_For_None()
{
// Arrange
var option = Option<string>.None();
// Act
var result = option.GetOrElse("default value");
// Assert
Assert.That(result, Is.EqualTo("default value"));
}
/// <summary>
/// 测试GetOrElse方法(工厂函数) - 验证Some值直接返回其值(不调用工厂)
/// </summary>
[Test]
public void OptionValueExtensions_GetOrElse_With_Factory_Should_Return_Value_For_Some()
{
// Arrange
var option = Option<string>.Some("actual value");
var factoryCalled = false;
// Act
var result = option.GetOrElse(() =>
{
factoryCalled = true;
return "factory value";
});
// Assert
Assert.That(result, Is.EqualTo("actual value"));
Assert.That(factoryCalled, Is.False);
}
/// <summary>
/// 测试GetOrElse方法(工厂函数) - 验证None值调用工厂函数
/// </summary>
[Test]
public void OptionValueExtensions_GetOrElse_With_Factory_Should_Call_Factory_For_None()
{
// Arrange
var option = Option<string>.None();
var factoryCalled = false;
// Act
var result = option.GetOrElse(() =>
{
factoryCalled = true;
return "factory value";
});
// Assert
Assert.That(result, Is.EqualTo("factory value"));
Assert.That(factoryCalled, Is.True);
}
/// <summary>
/// 测试OrElse方法 - 验证Some值返回自身
/// </summary>
[Test]
public void OptionValueExtensions_OrElse_Should_Return_Self_For_Some()
{
// Arrange
var option = Option<string>.Some("primary value");
var fallback = Option<string>.Some("fallback value");
// Act
var result = option.OrElse(fallback);
// Assert
Assert.That(result.IsSome, Is.True);
Assert.That(result.Value, Is.EqualTo("primary value"));
}
/// <summary>
/// 测试OrElse方法 - 验证None值返回备选Option
/// </summary>
[Test]
public void OptionValueExtensions_OrElse_Should_Return_Fallback_For_None()
{
// Arrange
var option = Option<string>.None();
var fallback = Option<string>.Some("fallback value");
// Act
var result = option.OrElse(fallback);
// Assert
Assert.That(result.IsSome, Is.True);
Assert.That(result.Value, Is.EqualTo("fallback value"));
}
/// <summary>
/// 测试OrElse方法 - 验证None值返回备选None
/// </summary>
[Test]
public void OptionValueExtensions_OrElse_Should_Return_Fallback_None_For_None()
{
// Arrange
var option = Option<string>.None();
var fallback = Option<string>.None();
// Act
var result = option.OrElse(fallback);
// Assert
Assert.That(result.IsNone, Is.True);
}
}

View File

@ -0,0 +1,171 @@
using GFramework.Core.functional.types;
using NUnit.Framework;
namespace GFramework.Core.Tests.functional.types;
/// <summary>
/// ResultExtensions扩展方法测试类用于验证Result类型的功能扩展方法
/// 包括映射、绑定、错误映射和匹配操作等功能的测试
/// </summary>
[TestFixture]
public class ResultExtensionsTests
{
/// <summary>
/// 测试Map方法 - 验证Success值能正确映射
/// </summary>
[Test]
public void Result_Map_Should_Transform_Success_Value()
{
// Arrange
var result = Result<string, string>.Success("hello");
// Act
var mappedResult = result.Map(s => s.Length);
// Assert
Assert.That(mappedResult.IsSuccess, Is.True);
Assert.That(mappedResult.SuccessValue, Is.EqualTo(5));
}
/// <summary>
/// 测试Map方法 - 验证Failure映射后仍保持Failure状态
/// </summary>
[Test]
public void Result_Map_Should_Keep_Failure_For_Failure()
{
// Arrange
var result = Result<string, string>.Failure("error occurred");
// Act
var mappedResult = result.Map(s => s.Length);
// Assert
Assert.That(mappedResult.IsFailure, Is.True);
Assert.That(mappedResult.ErrorValue, Is.EqualTo("error occurred"));
}
/// <summary>
/// 测试Bind方法 - 验证Success值能正确绑定到另一个Result
/// </summary>
[Test]
public void Result_Bind_Should_Transform_Success_To_Another_Result()
{
// Arrange
var result = Result<string, string>.Success("hello");
// Act
var boundResult = result.Bind(s =>
s.Length > 3 ? Result<int, string>.Success(s.Length) : Result<int, string>.Failure("Length too small"));
// Assert
Assert.That(boundResult.IsSuccess, Is.True);
Assert.That(boundResult.SuccessValue, Is.EqualTo(5));
}
/// <summary>
/// 测试Bind方法 - 验证Failure绑定后仍保持Failure状态
/// </summary>
[Test]
public void Result_Bind_Should_Keep_Failure_For_Failure()
{
// Arrange
var result = Result<string, string>.Failure("initial error");
// Act
var boundResult = result.Bind(s => Result<int, string>.Success(s.Length));
// Assert
Assert.That(boundResult.IsFailure, Is.True);
Assert.That(boundResult.ErrorValue, Is.EqualTo("initial error"));
}
/// <summary>
/// 测试Bind方法 - 验证Success值绑定到Failure的情况
/// </summary>
[Test]
public void Result_Bind_Should_Allow_Transition_To_Failure()
{
// Arrange
var result = Result<string, string>.Success("hi"); // 长度小于3
// Act
var boundResult = result.Bind(s =>
s.Length > 3 ? Result<int, string>.Success(s.Length) : Result<int, string>.Failure("Length too small"));
// Assert
Assert.That(boundResult.IsFailure, Is.True);
Assert.That(boundResult.ErrorValue, Is.EqualTo("Length too small"));
}
/// <summary>
/// 测试MapError方法 - 验证Failure错误值能正确映射
/// </summary>
[Test]
public void Result_MapError_Should_Transform_Failure_Error()
{
// Arrange
var result = Result<string, string>.Failure("original error");
// Act
var mappedErrorResult = result.MapError(err => $"Mapped: {err}");
// Assert
Assert.That(mappedErrorResult.IsFailure, Is.True);
Assert.That(mappedErrorResult.ErrorValue, Is.EqualTo("Mapped: original error"));
}
/// <summary>
/// 测试MapError方法 - 验证Success映射错误后仍保持Success状态
/// </summary>
[Test]
public void Result_MapError_Should_Keep_Success_For_Success()
{
// Arrange
var result = Result<string, string>.Success("success data");
// Act
var mappedErrorResult = result.MapError(err => $"Mapped: {err}");
// Assert
Assert.That(mappedErrorResult.IsSuccess, Is.True);
Assert.That(mappedErrorResult.SuccessValue, Is.EqualTo("success data"));
}
/// <summary>
/// 测试Match方法 - 验证Success值执行onSuccess分支
/// </summary>
[Test]
public void Result_Match_Should_Execute_OnSuccess_Branch_For_Success()
{
// Arrange
var result = Result<string, string>.Success("success data");
// Act
var matchedResult = result.Match(
onSuccess: data => $"Success: {data}",
onFailure: error => $"Error: {error}"
);
// Assert
Assert.That(matchedResult, Is.EqualTo("Success: success data"));
}
/// <summary>
/// 测试Match方法 - 验证Failure值执行onFailure分支
/// </summary>
[Test]
public void Result_Match_Should_Execute_OnFailure_Branch_For_Failure()
{
// Arrange
var result = Result<string, string>.Failure("something failed");
// Act
var matchedResult = result.Match(
onSuccess: data => $"Success: {data}",
onFailure: error => $"Error: {error}"
);
// Assert
Assert.That(matchedResult, Is.EqualTo("Error: something failed"));
}
}

View File

@ -0,0 +1,108 @@
using GFramework.Core.functional.types;
using NUnit.Framework;
namespace GFramework.Core.Tests.functional.types;
/// <summary>
/// Result类型测试类用于验证Result类型的基本功能
/// 包括创建Success和Failure实例、值访问等功能的测试
/// </summary>
[TestFixture]
public class ResultTests
{
/// <summary>
/// 测试创建Success实例 - 验证能正确创建成功结果
/// </summary>
[Test]
public void Result_Success_Should_Create_With_Value()
{
// Arrange
var value = "Success data";
// Act
var result = Result<string, string>.Success(value);
// Assert
Assert.That(result.IsSuccess, Is.True);
Assert.That(result.IsFailure, Is.False);
Assert.That(result.SuccessValue, Is.EqualTo(value));
}
/// <summary>
/// 测试访问Success值 - 验证能正确获取成功值
/// </summary>
[Test]
public void Result_Success_Value_Access_Should_Work()
{
// Arrange
var result = Result<string, string>.Success("test");
// Act & Assert
Assert.That(result.IsSuccess, Is.True);
Assert.That(result.SuccessValue, Is.EqualTo("test"));
}
/// <summary>
/// 测试访问Success的错误值 - 验证在成功状态下访问错误值抛出异常
/// </summary>
[Test]
public void Result_Success_Error_Access_Should_Throw_Exception()
{
// Arrange
var result = Result<string, string>.Success("success");
// Act & Assert
Assert.Throws<InvalidOperationException>(() =>
{
var _ = result.ErrorValue;
});
}
/// <summary>
/// 测试创建Failure实例 - 验证能正确创建失败结果
/// </summary>
[Test]
public void Result_Failure_Should_Create_With_Error()
{
// Arrange
var error = "Something went wrong";
// Act
var result = Result<string, string>.Failure(error);
// Assert
Assert.That(result.IsFailure, Is.True);
Assert.That(result.IsSuccess, Is.False);
Assert.That(result.ErrorValue, Is.EqualTo(error));
}
/// <summary>
/// 测试访问Failure值 - 验证能正确获取错误值
/// </summary>
[Test]
public void Result_Failure_Value_Access_Should_Work()
{
// Arrange
var result = Result<string, string>.Failure("error");
// Act & Assert
Assert.That(result.IsFailure, Is.True);
Assert.That(result.ErrorValue, Is.EqualTo("error"));
}
/// <summary>
/// 测试访问Failure的成功值 - 验证在失败状态下访问成功值抛出异常
/// </summary>
[Test]
public void Result_Failure_Success_Access_Should_Throw_Exception()
{
// Arrange
var result = Result<string, string>.Failure("error");
// Act & Assert
Assert.Throws<InvalidOperationException>(() =>
{
var _ = result.SuccessValue;
});
}
}

View File

@ -207,6 +207,182 @@ object obj = "Hello";
var str = obj.Cast<string>(); // "Hello"
```
### 6. Option Type - 可选值类型
位于 `GFramework.Core.functional.types` 命名空间,提供表示可能存在或不存在的值的类型。
#### 核心类型及用法:
- **Option&lt;T&gt;** - 表示可能包含值或不包含值的类型
```csharp
// 创建包含值的Option
var someValue = Option&lt;string&gt;.Some("Hello");
Console.WriteLine(someValue.IsSome); // True
Console.WriteLine(someValue.Value); // "Hello"
// 创建空的Option
var noValue = Option&lt;string&gt;.None();
Console.WriteLine(noValue.IsNone); // True
```
#### Option扩展方法
- **Map** - 对Option中的值进行映射转换
```csharp
var someValue = Option&lt;string&gt;.Some("hello");
var lengthOption = someValue.Map(s => s.Length); // Some(5)
var noneValue = Option&lt;string&gt;.None();
var noneLength = noneValue.Map(s => s.Length); // None
```
- **Bind** - 将Option中的值转换为另一个Option
```csharp
var someValue = Option&lt;string&gt;.Some("hello");
var result = someValue.Bind(s => s.Length > 3 ? Option&lt;int&gt;.Some(s.Length) : Option&lt;int&gt;.None()); // Some(5)
var shortValue = Option&lt;string&gt;.Some("hi");
var result2 = shortValue.Bind(s => s.Length > 3 ? Option&lt;int&gt;.Some(s.Length) : Option&lt;int&gt;.None()); // None
```
- **Filter** - 根据条件过滤Option中的值
```csharp
var someValue = Option&lt;string&gt;.Some("hello");
var filtered = someValue.Filter(s => s.Length > 3); // Some("hello")
var filtered2 = someValue.Filter(s => s.Length > 10); // None
```
- **Match** - 模式匹配Option的状态
```csharp
var someValue = Option&lt;string&gt;.Some("hello");
var result = someValue.Match(
some: s => $"Value: {s}",
none: () => "No value"
); // "Value: hello"
var noneValue = Option&lt;string&gt;.None();
var result2 = noneValue.Match(
some: s => $"Value: {s}",
none: () => "No value"
); // "No value"
```
- **GetOrElse** - 获取值或返回默认值
```csharp
var someValue = Option&lt;string&gt;.Some("hello");
var value1 = someValue.GetOrElse("default"); // "hello"
var noneValue = Option&lt;string&gt;.None();
var value2 = noneValue.GetOrElse("default"); // "default"
```
- **OrElse** - 当前Option为空时返回备选Option
```csharp
var someValue = Option&lt;string&gt;.Some("primary");
var result1 = someValue.OrElse(Option&lt;string&gt;.Some("fallback")); // Some("primary")
var noneValue = Option&lt;string&gt;.None();
var result2 = noneValue.OrElse(Option&lt;string&gt;.Some("fallback")); // Some("fallback")
```
### 7. Result Type - 结果类型
位于 `GFramework.Core.functional.types` 命名空间,提供表示成功或失败结果的类型。
#### 核心类型及用法:
- **Result&lt;TSuccess, TError&gt;** - 表示可能成功或失败的计算结果
```csharp
// 创建成功的结果
var successResult = Result&lt;string, string&gt;.Success("Operation successful");
Console.WriteLine(successResult.IsSuccess); // True
Console.WriteLine(successResult.SuccessValue); // "Operation successful"
// 创建失败的结果
var failureResult = Result&lt;string, string&gt;.Failure("Operation failed");
Console.WriteLine(failureResult.IsFailure); // True
Console.WriteLine(failureResult.ErrorValue); // "Operation failed"
```
#### Result扩展方法
- **Map** - 对成功值进行映射转换
```csharp
var successResult = Result&lt;string, string&gt;.Success("hello");
var lengthResult = successResult.Map(s => s.Length); // Success(5)
var failureResult = Result&lt;string, string&gt;.Failure("error");
var lengthResult2 = failureResult.Map(s => s.Length); // Failure("error")
```
- **Bind** - 将成功值转换为另一个Result
```csharp
var successResult = Result&lt;string, string&gt;.Success("hello");
var result = successResult.Bind(s =>
s.Length > 3 ?
Result&lt;int, string&gt;.Success(s.Length) :
Result&lt;int, string&gt;.Failure("Length too small"));
// Result&lt;int, string&gt;.Success(5)
```
- **MapError** - 对错误值进行映射转换
```csharp
var failureResult = Result&lt;string, string&gt;.Failure("original error");
var mappedErrorResult = failureResult.MapError(err => $"Mapped: {err}");
// Result&lt;string, string&gt;.Failure("Mapped: original error")
```
- **Match** - 模式匹配Result的状态
```csharp
var successResult = Result&lt;string, string&gt;.Success("data");
var result = successResult.Match(
onSuccess: data => $"Success: {data}",
onFailure: error => $"Error: {error}"
); // "Success: data"
var failureResult = Result&lt;string, string&gt;.Failure("error");
var result2 = failureResult.Match(
onSuccess: data => $"Success: {data}",
onFailure: error => $"Error: {error}"
); // "Error: error"
```
### 8. Nullable Extensions - 可空类型扩展
位于 `GFramework.Core.functional.types` 命名空间提供将可空类型转换为Option类型的方法。
#### 方法列表及用法:
- **ToOption** - 将可空类型转换为Option
```csharp
// 引用类型可空转换
string? stringValue = "Hello";
var someOption = stringValue.ToOption(); // Some("Hello")
string? nullString = null;
var noneOption = nullString.ToOption(); // None
// 值类型可空转换
int? intValue = 42;
var someIntOption = intValue.ToOption(); // Some(42)
int? nullInt = null;
var noneIntOption = nullInt.ToOption(); // None
```
## 使用示例
### 链式操作