สถานการณ์เมตาโปรแกรมมิงแบบเบื้องต้น
ตัวช่วยที่ขับเคลื่อนด้วยแอตทริบิวต์: ป้ายแสดงผล การตรวจสอบฟิลด์ที่จำเป็น ตัวสร้างอินสแตนซ์ขนาดเล็ก และการทำซีเรียลไลซ์ลักษณะ CSV พร้อมคำแนะนำด้านความปลอดภัยที่ชัดเจน
สถานการณ์เมตาโปรแกรมมิงแบบเบื้องต้น เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 3 บทเรียน
แผนและขอบเขต
เป้าหมาย: ควบคุมพฤติกรรมเล็ก ๆ ด้วยแอตทริบิวต์
- จับคู่ป้ายกำกับ
- ตรวจสอบฟิลด์ที่จำเป็น
- ตัวสร้างอินสแตนซ์DI ขนาดเล็ก
- แปลงเป็นอนุกรมเป็นข้อความลักษณะ CSV
ป้ายกำกับแอตทริบิวต์
ใส่ DisplayName ให้กับคุณสมบัติ แล้วใช้การสะท้อนโครงสร้างโปรแกรมเพื่อพิมพ์ป้ายกำกับที่อ่านเข้าใจง่าย
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.Property)]
public sealed class DisplayNameAttribute : Attribute
{
public string Text { get; private set; }
public DisplayNameAttribute(string text) { Text = text; }
}
public sealed class User
{
[DisplayName("User Id")]
public int Id { get; set; }
[DisplayName("Full Name")]
public string Name { get; set; }
}
public class Program
{
static void PrintWithLabels(object o)
{
if (o == null) throw new ArgumentNullException("o");
Type t = o.GetType();
foreach (PropertyInfo p in t.GetProperties())
{
object[] at = p.GetCustomAttributes(typeof(DisplayNameAttribute), false);
string label = at.Length > 0 ? ((DisplayNameAttribute)at[0]).Text : p.Name;
object val = p.GetValue(o, null);
Console.WriteLine(label + ": " + (val == null ? "null" : val.ToString()));
}
}
public static void Main(string[] args)
{
User u = new User { Id = 1, Name = "Ada" };
PrintWithLabels(u);
}
}
การตรวจสอบแอตทริบิวต์
ทำเครื่องหมายคุณสมบัติด้วย Required ตัวตรวจสอบขนาดเล็กจะตรวจสอบและรายงานฟิลด์แรกที่ขาดหายไป
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.Property)]
public sealed class RequiredAttribute : Attribute { }
public sealed class Product
{
[Required] public string Name { get; set; }
public decimal Price { get; set; }
}
public class Program
{
static bool Validate(object obj, out string error)
{
error = null;
if (obj == null) { error = "object is null"; return false; }
Type t = obj.GetType();
foreach (PropertyInfo p in t.GetProperties())
{
object[] req = p.GetCustomAttributes(typeof(RequiredAttribute), false);
if (req.Length > 0)
{
object v = p.GetValue(obj, null);
if (v == null || (v is string && string.IsNullOrEmpty((string)v)))
{
error = "Required property missing: " + p.Name;
return false;
}
}
}
return true;
}
public static void Main(string[] args)
{
Product ok = new Product { Name = "Mouse", Price = 10m };
Product bad = new Product { Name = null, Price = 5m };
string e;
Console.WriteLine(Validate(ok, out e) ? "OK" : e);
Console.WriteLine(Validate(bad, out e) ? "OK" : e);
}
}
ตัวสร้างอินสแตนซ์ขนาดเล็ก
ตัวสร้างอินสแตนซ์ขนาดเล็กจะจับคู่ชื่อกับพารามิเตอร์แต่ละตัวของตัวสร้าง หากไม่มีข้อมูลก็จะใช้ค่าเริ่มต้น
using System;
using System.Reflection;
using System.Collections.Generic;
public sealed class Repo { public string Name; public Repo(string name){ Name = name; } }
public sealed class Service
{
public Repo R; public int Timeout;
public Service(Repo repo, int timeout){ R = repo; Timeout = timeout; }
}
public class Program
{
static object CreateWithArgs(Type t, IDictionary<string, object> args)
{
if (t == null) throw new ArgumentNullException("t");
if (args == null) args = new Dictionary<string, object>();
ConstructorInfo[] ctors = t.GetConstructors();
if (ctors.Length == 0) throw new InvalidOperationException("No public constructor");
ConstructorInfo ci = ctors[0];
ParameterInfo[] ps = ci.GetParameters();
object[] argv = new object[ps.Length];
for (int i = 0; i < ps.Length; i++)
{
object val;
if (args.TryGetValue(ps[i].Name, out val)) argv[i] = val;
else if (ps[i].ParameterType.IsValueType) argv[i] = Activator.CreateInstance(ps[i].ParameterType);
else argv[i] = null;
}
return ci.Invoke(argv);
}
public static void Main(string[] args)
{
IDictionary<string, object> map = new Dictionary<string, object>();
map["repo"] = new Repo("Main");
map["timeout"] = 30;
Service s = (Service)CreateWithArgs(typeof(Service), map);
Console.WriteLine(s.R.Name + " / " + s.Timeout);
}
}
CSV ด้วยแอตทริบิวต์
จัดลำดับคอลัมน์ด้วย CsvOrder และจัดการเครื่องหมายจุลภาคกับเครื่องหมายอัญประกาศให้ถูกต้อง
using System;
using System.Reflection;
using System.Text;
using System.Globalization;
[AttributeUsage(AttributeTargets.Property)]
public sealed class CsvOrderAttribute : Attribute
{
public int Index { get; private set; }
public CsvOrderAttribute(int index){ Index = index; }
}
public sealed class Row
{
[CsvOrder(0)] public int Id { get; set; }
[CsvOrder(1)] public string Name { get; set; }
[CsvOrder(2)] public decimal Price { get; set; }
}
public class Program
{
static int GetIndex(PropertyInfo p)
{
object[] at = p.GetCustomAttributes(typeof(CsvOrderAttribute), false);
return at.Length > 0 ? ((CsvOrderAttribute)at[0]).Index : Int32.MaxValue;
}
static string ToCsv(object o)
{
if (o == null) throw new ArgumentNullException("o");
Type t = o.GetType();
PropertyInfo[] props = t.GetProperties();
Array.Sort(props, delegate(PropertyInfo a, PropertyInfo b)
{
int ia = GetIndex(a), ib = GetIndex(b);
return ia.CompareTo(ib);
});
StringBuilder sb = new StringBuilder();
for (int i = 0; i < props.Length; i++)
{
object v = props[i].GetValue(o, null);
string cell = v == null ? "" : Convert.ToString(v, CultureInfo.InvariantCulture);
if (i > 0) sb.Append(",");
sb.Append(cell);
}
return sb.ToString();
}
public static void Main(string[] args)
{
Row r = new Row { Id = 7, Name = "Cable, HDMI", Price = 12.5m };
Console.WriteLine(ToCsv(r));
}
}
เคล็ดลับและความปลอดภัย
เคล็ดลับ:
- เลือกใช้ typeof และข้อมูลเมทาดาทาที่เก็บไว้ในเส้นทางการทำงานที่ใช้บ่อย
- ตรวจสอบสมาชิกก่อนเรียกใช้ GetValue หรือ Invoke
- ทำให้เมธอดช่วยเหลือมีขนาดเล็กและผ่านการทดสอบหน่วย
- หยุดทำงานทันทีพร้อมข้อความที่เป็นประโยชน์
แนวทางการใช้การสะท้อนโครงสร้างโปรแกรม
สรุป
สรุป: แอตทริบิวต์สามารถควบคุมตัวแปลงข้อมูล ตัวตรวจสอบ ตัวสร้างอินสแตนซ์ และตัวแปลงอนุกรมขนาดเล็กได้ ควรใช้การสะท้อนโครงสร้างโปรแกรมให้น้อยและปลอดภัย
คำถามที่พบบ่อย
บทเรียน “สถานการณ์เมตาโปรแกรมมิงแบบเบื้องต้น” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “สถานการณ์เมตาโปรแกรมมิงแบบเบื้องต้น” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 3 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “สถานการณ์เมตาโปรแกรมมิงแบบเบื้องต้น”
ตัวช่วยที่ขับเคลื่อนด้วยแอตทริบิวต์: ป้ายแสดงผล การตรวจสอบฟิลด์ที่จำเป็น ตัวสร้างอินสแตนซ์ขนาดเล็ก และการทำซีเรียลไลซ์ลักษณะ CSV พร้อมคำแนะนำด้านความปลอดภัยที่ชัดเจน คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 3 บทเรียน
บทเรียน “สถานการณ์เมตาโปรแกรมมิงแบบเบื้องต้น” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- Type, MethodInfo, การสร้างอินสแตนซ์ และแอตทริบิวต์แบบกำหนดเอง
- ข้อมูลระดับซอร์ส (แอตทริบิวต์ Caller)
- สถานการณ์เมตาโปรแกรมมิงแบบเบื้องต้น