การย้ายโค้ดเบสไปยัง 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การเปิดใช้และทำความเข้าใจ NRT
- คำอธิบายประกอบ: ?, !, MaybeNull และ NotNull
- ตัวดำเนินการเงื่อนไข Null และรวมค่า Null
- การย้ายโค้ดเบสไปยัง NRT