mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-23 03:04:29 +08:00
feat(functional): 添加Result类型及其扩展方法支持
- 引入Result<TSuccess, TError>结构体用于表示可能成功或失败的计算结果 - 实现Result类型的Success和Failure静态工厂方法 - 添加SuccessValue和ErrorValue属性用于获取对应值 - 创建ResultExtensions扩展类提供Map、Bind、MapError和Match方法 - 在FunctionExtensions中添加TryResult方法将异常安全执行封装为Result类型 - 更新Try方法的文档注释以反映新的功能和返回类型
This commit is contained in:
parent
fd3a9ae9e0
commit
c9dd969b05
@ -11,6 +11,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using GFramework.Core.functional.types;
|
||||
|
||||
namespace GFramework.Core.functional.functions;
|
||||
|
||||
/// <summary>
|
||||
@ -79,28 +81,31 @@ public static class FunctionExtensions
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Try:安全执行,捕获异常
|
||||
/// 尝试执行一个转换函数,并将结果包装在Result对象中,捕获可能发生的异常
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">输入值的类型</typeparam>
|
||||
/// <typeparam name="TResult">函数返回结果的类型</typeparam>
|
||||
/// <param name="value">要传递给函数的输入值</param>
|
||||
/// <param name="func">要安全执行的函数</param>
|
||||
/// <returns>包含执行状态、结果和错误信息的元组</returns>
|
||||
public static (bool success, TResult? result, Exception? error) Try<TSource, TResult>(
|
||||
/// <typeparam name="TResult">转换函数返回值的类型</typeparam>
|
||||
/// <param name="value">要进行转换操作的源值</param>
|
||||
/// <param name="func">用于转换源值的函数委托</param>
|
||||
/// <returns>如果转换成功则返回包含结果的成功状态,如果发生异常则返回包含异常信息的失败状态</returns>
|
||||
public static Result<TResult, Exception> TryResult<TSource, TResult>(
|
||||
this TSource value,
|
||||
Func<TSource, TResult> func)
|
||||
{
|
||||
// 执行转换函数并处理可能的异常
|
||||
try
|
||||
{
|
||||
return (true, func(value), null);
|
||||
return Result<TResult, Exception>.Success(func(value));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, default, ex);
|
||||
return Result<TResult, Exception>.Failure(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Memoize:缓存函数结果
|
||||
/// </summary>
|
||||
|
||||
91
GFramework.Core/functional/types/Result.cs
Normal file
91
GFramework.Core/functional/types/Result.cs
Normal file
@ -0,0 +1,91 @@
|
||||
// Copyright (c) 2026 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.functional.types;
|
||||
|
||||
/// <summary>
|
||||
/// 表示一个可能成功也可能失败的计算结果
|
||||
/// </summary>
|
||||
/// <typeparam name="TSuccess">成功值的类型</typeparam>
|
||||
/// <typeparam name="TError">错误值的类型</typeparam>
|
||||
public readonly struct Result<TSuccess, TError>
|
||||
{
|
||||
private readonly TSuccess _success;
|
||||
private readonly TError _error;
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前结果是否为成功状态
|
||||
/// </summary>
|
||||
public bool IsSuccess { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前结果是否为失败状态
|
||||
/// </summary>
|
||||
public bool IsFailure => !IsSuccess;
|
||||
|
||||
/// <summary>
|
||||
/// 使用成功值初始化Result实例
|
||||
/// </summary>
|
||||
/// <param name="success">成功值</param>
|
||||
private Result(TSuccess success)
|
||||
{
|
||||
_success = success;
|
||||
_error = default!;
|
||||
IsSuccess = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用错误值初始化Result实例
|
||||
/// </summary>
|
||||
/// <param name="error">错误值</param>
|
||||
private Result(TError error)
|
||||
{
|
||||
_error = error;
|
||||
_success = default!;
|
||||
IsSuccess = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个表示成功的Result实例
|
||||
/// </summary>
|
||||
/// <param name="value">成功值</param>
|
||||
/// <returns>包含成功值的Result实例</returns>
|
||||
public static Result<TSuccess, TError> Success(TSuccess value)
|
||||
=> new(value);
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个表示失败的Result实例
|
||||
/// </summary>
|
||||
/// <param name="error">错误值</param>
|
||||
/// <returns>包含错误值的Result实例</returns>
|
||||
public static Result<TSuccess, TError> Failure(TError error)
|
||||
=> new(error);
|
||||
|
||||
/// <summary>
|
||||
/// 获取成功值,如果结果为失败则抛出异常
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">当结果为失败时抛出</exception>
|
||||
public TSuccess SuccessValue =>
|
||||
IsSuccess
|
||||
? _success
|
||||
: throw new InvalidOperationException("Result is Failure");
|
||||
|
||||
/// <summary>
|
||||
/// 获取错误值,如果结果为成功则抛出异常
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">当结果为成功时抛出</exception>
|
||||
public TError ErrorValue =>
|
||||
IsFailure
|
||||
? _error
|
||||
: throw new InvalidOperationException("Result is Success");
|
||||
}
|
||||
54
GFramework.Core/functional/types/ResultExtensions.cs
Normal file
54
GFramework.Core/functional/types/ResultExtensions.cs
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright (c) 2026 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.functional.types;
|
||||
|
||||
public static class ResultExtensions
|
||||
{
|
||||
public static Result<TResult, TError> Map<TSuccess, TResult, TError>(
|
||||
this Result<TSuccess, TError> result,
|
||||
Func<TSuccess, TResult> mapper)
|
||||
{
|
||||
return result.IsSuccess
|
||||
? Result<TResult, TError>.Success(mapper(result.SuccessValue))
|
||||
: Result<TResult, TError>.Failure(result.ErrorValue);
|
||||
}
|
||||
|
||||
public static Result<TResult, TError> Bind<TSuccess, TResult, TError>(
|
||||
this Result<TSuccess, TError> result,
|
||||
Func<TSuccess, Result<TResult, TError>> binder)
|
||||
{
|
||||
return result.IsSuccess
|
||||
? binder(result.SuccessValue)
|
||||
: Result<TResult, TError>.Failure(result.ErrorValue);
|
||||
}
|
||||
|
||||
public static Result<TSuccess, TNewError> MapError<TSuccess, TError, TNewError>(
|
||||
this Result<TSuccess, TError> result,
|
||||
Func<TError, TNewError> mapper)
|
||||
{
|
||||
return result.IsFailure
|
||||
? Result<TSuccess, TNewError>.Failure(mapper(result.ErrorValue))
|
||||
: Result<TSuccess, TNewError>.Success(result.SuccessValue);
|
||||
}
|
||||
|
||||
public static TResult Match<TSuccess, TError, TResult>(
|
||||
this Result<TSuccess, TError> result,
|
||||
Func<TSuccess, TResult> onSuccess,
|
||||
Func<TError, TResult> onFailure)
|
||||
{
|
||||
return result.IsSuccess
|
||||
? onSuccess(result.SuccessValue)
|
||||
: onFailure(result.ErrorValue);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user