TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 549 subscribers
Post #318 229
درک الگوی Result 🤔

الگوی Result یک الگوی طراحی است که نتیجه یک عملیات را کپسوله می‌کند، که می‌تواند یا موفقیت‌آمیز باشد یا یک شکست. به جای پرتاب استثناها، متدها یک آبجکت Result را برمی‌گردانند که نشان می‌دهد آیا عملیات موفق شده یا شکست خورده است، همراه با هرگونه داده یا پیام خطای مرتبط.

آبجکت Result از بخش‌های زیر تشکیل شده است:

🔹 IsSuccess/IsError:
یک مقدار بولین که نشان می‌دهد آیا عملیات موفقیت‌آمیز بوده است یا نه.

🔹 Value:
مقدار نتیجه زمانی که عملیات موفقیت‌آمیز است.

🔹 Error:
یک پیام یا آبجکت خطا زمانی که عملیات شکست می‌خورد.

بیایید یک مثال ساده از نحوه پیاده‌سازی یک آبجکت Result را بررسی کنیم: 🎁
public class Result<T>
{
public bool IsSuccess { get; }
public bool IsFailure => !IsSuccess;
public T? Value { get; }
public string? Error { get; }

private Result(bool isSuccess, T? value, string? error)
{
IsSuccess = isSuccess;
Value = value;
Error = error;
}

public static Result<T> Success(T value)
{
return new Result<T>(true, value, null);
}

public static Result<T> Failure(string error)
{
return new Result<T>(false, default(T), error);
}
}


در اینجا ما یک کلاس جنریک Result تعریف کرده‌ایم که می‌تواند یا یک مقدار موفقیت‌آمیز یا یک خطا را در خود نگه دارد. برای ایجاد آبجکت Result می‌توانید از متد استاتیک Success یا Failure استفاده کنید.

بیایید پیاده‌سازی endpoint قبلی Create Shipment را با الگوی Result خود بازنویسی کنیم: ✅
public async Task<Result<ShipmentResponse>> CreateAsync(
CreateShipmentCommand request,
CancellationToken cancellationToken)
{
var shipmentAlreadyExists = await context.Shipments
.Where(s => s.OrderId == request.OrderId)
.AnyAsync(cancellationToken);

if (shipmentAlreadyExists)
{
return Result.Failure<ShipmentResponse>(
$"Shipment for order '{request.OrderId}' is already created");
}

var shipment = request.MapToShipment(shipmentNumber);

context.Shipments.Add(shipiment);

await context.SaveChangesAsync(cancellationToken);

var response = shipment.MapToResponse();

return Result.Success(response);
}

در اینجا متد <Result<ShipmentResponse را برمی‌گرداند که ShipmentResponse را داخل یک کلاس Result می‌پیچد.

وقتی یک shipment از قبل در دیتابیس وجود داشته باشد، ما Result.Failure را با یک پیام متناظر برمی‌گردانیم. وقتی یک درخواست موفق می‌شود، ما Result.Success را برمی‌گردانیم.

در اینجا نحوه مدیریت یک آبجکت Result در endpoint آمده است: 👇
public void MapEndpoint(WebApplication app)
{
app.MapPost("/api/v1/shipments", Handle);
}

private static async Task<IResult> Handle(
[FromBody] CreateShipmentRequest request,
IShipmentService service,
CancellationToken cancellationToken)
{
var command = request.MapToCommand();
var response = await service.CreateAsync(command, cancellationToken);

return response.IsSuccess ? Results.Ok(response.Value) : Results.Conflict(response.Error);
}

شما باید بررسی کنید که آیا پاسخ موفقیت‌آمیز است یا شکست خورده و یک نتیجه HTTP مناسب را برگردانید. حالا کد قابل پیش‌بینی‌تر به نظر می‌رسد و راحت‌تر خوانده می‌شود، درست است؟ 😉
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →