0Pricing
C# Academy · บทเรียน

การย้ายโค้ดเบสไปยัง NRT

ใช้กลยุทธ์การย้ายแบบเป็นระยะ ได้แก่ เปิดใช้คำเตือน เพิ่มคำอธิบายประกอบให้ API แก้ไขปัญหา และหลีกเลี่ยงผลบวกลวง

การย้ายโค้ดเบสไปยัง NRT เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

ความท้าทายในการย้ายระบบ

การเปิดใช้ NRT ในฐานโค้ดเดิมมักทำให้เกิดคำเตือนหลายร้อยรายการ การแก้ไขทั้งหมดในคราวเดียวมีความเสี่ยง ดังนั้นให้ใช้ การย้ายระบบเป็นระยะ โดยเปิดใช้คำเตือนทีละขั้น แก้ไขทีละไฟล์ และรักษาความคืบหน้าอย่างต่อเนื่อง

ขั้นตอนที่ 1: เปิดใช้เฉพาะคำเตือน

เริ่มด้วย <Nullable>warnings</Nullable> แทน enable วิธีนี้จะเปิดใช้คำเตือนโดยไม่ถือว่าโค้ดที่ไม่มีคำอธิบายประกอบเป็นข้อผิดพลาด จึงเป็นจุดเริ่มต้นที่ปลอดภัย

<!-- Phase 1: warnings only, no breaking change -->
<PropertyGroup>
  <Nullable>warnings</Nullable>
</PropertyGroup>

<!-- Phase 2: full enable per file as you migrate -->
<!-- Phase 3: switch to enable globally when done -->

ขั้นตอนที่ 2: เปิดใช้ทีละไฟล์

เพิ่ม #nullable enable ไว้ด้านบนของแต่ละไฟล์เมื่อเริ่มทำงานกับไฟล์นั้น วิธีนี้จำกัดการเปลี่ยนแปลงไว้เฉพาะไฟล์ที่กำลังแก้ไข ทำให้การตรวจทานทำได้ง่ายขึ้น

#nullable enable
// Now this file has full NRT analysis

public class OrderService
{
    private readonly IOrderRepository _repo;
    // Compiler now warns about uninitialized non-nullable fields,
    // unsafe dereferences, and assignment to non-nullable

    public OrderService(IOrderRepository repo) => _repo = repo;
}

// Other files without #nullable enable are still unchecked

การจัดหมวดหมู่คำเตือน

คำเตือนแบ่งออกเป็นสองประเภท ได้แก่ ประเภทที่ระงับได้อย่างปลอดภัย เช่น เอนทิตีจากระบบแมปออบเจ็กต์กับฐานข้อมูลและฟิลด์ที่ DI เติมให้ และ ข้อผิดพลาดจริง เช่น ค่าที่เป็น null จริงถูกนำไปอ้างอิง ควรแยกแยะให้ได้ก่อนระงับคำเตือนใด ๆ

// Category 1: safe to suppress with null!
// EF Core navigation properties — set by EF, never null in practice
public class Order
{
    public Customer Customer { get; set; } = null!;
}

// Category 2: real bug — must fix
public string GetFullName()
{
    return FirstName + " " + LastName; // LastName was string? -- BUG!
}

การแก้คำเตือนตัวสร้าง CS8618

CS8618 เกิดขึ้นเมื่อไม่ได้กำหนดคุณสมบัติที่ไม่ยอมรับค่า null ในตัวสร้าง วิธีแก้ที่แนะนำคือบังคับให้ส่งค่านั้นผ่านตัวสร้าง ใช้ = null! เฉพาะกับค่าที่เฟรมเวิร์กเป็นผู้กำหนดเท่านั้น

// BEFORE (CS8618)
public class Product
{
    public string Name { get; set; }   // warning
    public Category Category { get; set; } // warning
}

// AFTER — constructor required:
public class Product
{
    public string Name { get; set; }
    public Category Category { get; set; }

    public Product(string name, Category category)
    {
        Name = name;
        Category = category;
    }
}

การจัดการส่วนติดต่อโปรแกรมรุ่นเก่า

ส่วนติดต่อโปรแกรมจากบุคคลที่สามหรือรุ่นเก่าอาจไม่มีคำอธิบายประกอบ ชนิดค่าที่ส่งกลับของส่วนติดต่อเหล่านี้จึงเป็นแบบ ไม่ระบุสถานะ คือไม่ระบุทั้งว่ายอมรับค่า null หรือไม่ ควรกำหนดผลลัพธ์ให้กับตัวแปรที่ยอมรับค่า null เพื่อให้ชัดเจน

// Legacy API returns 'string' but might be null (oblivious type)
string? legacyResult = OldLibrary.GetValue(); // store as nullable
if (legacyResult is null) return;

// Or convert at the boundary:
string safe = OldLibrary.GetValue() ?? "";

// For third-party types, check if they have NRT annotations:
// NuGet packages often add nullable annotations in newer versions

การใช้ #pragma เพื่อระงับคำเตือนเฉพาะรายการ

เมื่อคำเตือนเป็นผลบวกลวงจริง ๆ และ = null! ทำให้โค้ดดูรบกวนเกินไป ให้ใช้ #pragma warning disable โดยจำกัดขอบเขตไว้ที่บรรทัดนั้นโดยเฉพาะ

// Suppress for a specific case with explanation:
#pragma warning disable CS8618 // ORM populates this via reflection
public DbSet<Product> Products { get; set; }
#pragma warning restore CS8618

// Or inline with a comment:
public DbSet<Order> Orders { get; set; } = null!; // set by EF Core

การถือว่าคำเตือน NRT เป็นข้อผิดพลาด

เมื่อแก้คำเตือนทั้งหมดในไฟล์แล้ว ให้เพิ่ม <WarningsAsErrors>Nullable</WarningsAsErrors> หรือใช้การบังคับใช้ในการตรวจสอบต่อเนื่อง เพื่อป้องกันการถดถอย ปัญหา nullable ใหม่ใด ๆ จะทำให้การสร้างโปรเจกต์ไม่ผ่าน

<!-- After full migration: treat nullable warnings as build errors -->
<PropertyGroup>
  <Nullable>enable</Nullable>
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  <!-- Or selectively: -->
  <!-- <WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors> -->
</PropertyGroup>

การใส่คำอธิบายประกอบให้ส่วนติดต่อโปรแกรมสาธารณะ

เมื่อผู้อื่นนำไลบรารีของคุณไปใช้งาน คำอธิบายประกอบ NRT จะกลายเป็นส่วนหนึ่งของสัญญาส่วนติดต่อโปรแกรมสาธารณะ ให้ส่งคืน T? เมื่อผลลัพธ์อาจเป็น null และส่งคืน T เมื่อรับประกันได้ว่าจะไม่เป็น null

public interface IProductService
{
    // Contract: FindById MAY return null, GetById never does
    Product? FindById(int id);
    Product  GetById(int id);  // throws if not found

    // Collection: never null (may be empty)
    IReadOnlyList<Product> GetAll();

    // String: may be empty but not null
    string GetSummary(int id);
}

เมตริกและการติดตามการย้ายระบบ

ติดตามความคืบหน้าด้วยการนับไฟล์ที่มี #nullable enable หรือเรียกใช้ dotnet build 2>&1 | grep CS86 ในการตรวจสอบต่อเนื่อง และกำหนดวันที่เป้าหมายสำหรับการย้ายทั้งโปรเจกต์ให้เสร็จสมบูรณ์

# Count NRT warnings in current build
dotnet build 2>&1 | grep -c 'CS860[0-9]\|CS861[0-9]\|CS862[0-9]'

# List files still missing #nullable enable
grep -rL '#nullable enable' src/ --include='*.cs'

# Track in CI: fail if warning count increases
# Set a budget: warnings <= N, where N decreases each sprint

การตรวจสอบอย่างรวดเร็ว

การกำหนดค่า = null! ให้กับคุณสมบัติที่ไม่ยอมรับค่า null สื่อความหมายว่าอย่างไร

สรุป: การย้ายระบบไปใช้ NRT

ประเด็นสำคัญ:

  • ใช้การย้ายระบบเป็นระยะ: โหมดคำเตือน → เปิดใช้ทีละไฟล์ → เปิดใช้ทั่วทั้งโปรเจกต์
  • แยกแยะข้อผิดพลาดจริงเพื่อแก้ไข ออกจากรูปแบบของระบบแมปออบเจ็กต์กับฐานข้อมูลและ DI ที่ใช้ = null!
  • แก้ CS8618 ด้วยการบังคับให้กำหนดค่าในตัวสร้าง ไม่ใช่การระงับคำเตือน
  • กำหนดผลลัพธ์จากส่วนติดต่อโปรแกรมรุ่นเก่าให้กับตัวแปร T? เพื่อระบุสถานะให้ชัดเจน
  • ถือว่าคำเตือน nullable เป็นข้อผิดพลาดในการตรวจสอบต่อเนื่อง เพื่อป้องกันการถดถอย
  • ส่วนติดต่อโปรแกรมสาธารณะที่มีคำอธิบายประกอบจะกลายเป็นสัญญาที่ชัดเจนสำหรับผู้เรียกใช้

คำถามที่พบบ่อย

บทเรียน “การย้ายโค้ดเบสไปยัง NRT” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การย้ายโค้ดเบสไปยัง NRT” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การย้ายโค้ดเบสไปยัง NRT”

ใช้กลยุทธ์การย้ายแบบเป็นระยะ ได้แก่ เปิดใช้คำเตือน เพิ่มคำอธิบายประกอบให้ API แก้ไขปัญหา และหลีกเลี่ยงผลบวกลวง คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การย้ายโค้ดเบสไปยัง NRT” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม

ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การเปิดใช้และทำความเข้าใจ NRT
  2. คำอธิบายประกอบ: ?, !, MaybeNull และ NotNull
  3. ตัวดำเนินการเงื่อนไข Null และรวมค่า Null
  4. การย้ายโค้ดเบสไปยัง NRT
← กลับไปที่ C# Academy