ไม่สามารถ Implement Interface ใน Anonymous Types ได้ ต้องสร้าง Type ของตัวเอง
Anonymous Types ให้วิธีสะดวกในการ Encapsulate Set ของ Read-only Properties เข้าเป็น Object เดียวโดยไม่ต้อง Define Type ก่อน
Type Name ถูก Generate โดย Compiler และไม่พร้อมใช้งานที่ Source Code Level Type ของแต่ละ Property ถูก Infer โดย Compiler
สร้าง Anonymous Types โดยใช้ Operator new ร่วมกับ Object Initializer
ตัวอย่าง Anonymous Type
class Program {
public static void Main() {
var v = new { Amount = 108, Message = "Test" };
Console.WriteLine(v.Amount + v.Message);
Console.ReadLine();
}
}
Output
108Test
ทำไม Anonymous Types ไม่สามารถ Implement Interface ได้
- Anonymous Types เป็น
sealed(Compiler-generated) - ไม่มีชื่อ Type ที่เข้าถึงได้ใน Source Code
- Properties เป็น Read-only เท่านั้น
- Compiler สร้าง Equals/GetHashCode/ToString อัตโนมัติ
- ไม่สามารถมี Methods, Constructors, หรือ Interface Implementation
ทางเลือกแทน Anonymous Types
1. Named Class/Struct (แนะนำ)
public interface IResult {
int Amount { get; }
string Message { get; }
}
public class Result : IResult {
public int Amount { get; }
public string Message { get; }
public Result(int amount, string message) {
Amount = amount;
Message = message;
}
}
// Usage
IResult result = new Result(108, "Test");
2. Record Types (C# 9.0+) - Concise Immutable Types
public interface IResult {
int Amount { get; }
string Message { get; }
}
// Record Auto-implements Properties, Equality, With-expression
public record Result(int Amount, string Message) : IResult;
// Usage
IResult result = new Result(108, "Test");
var updated = result with { Amount = 200 }; // Immutable Update
3. Dynamic/ExpandoObject (Runtime Flexibility)
using System.Dynamic;
dynamic obj = new ExpandoObject();
obj.Amount = 108;
obj.Message = "Test";
// แต่ไม่มี Compile-time Safety และ Interface Checking
4. Anonymous Types สำหรับ Internal/Projection เท่านั้น
// ใช้ได้เฉพาะภายใน Method เดียวกัน (Local Scope)
var projection = users.Select(u => new {
u.Id,
u.Name,
FullName = u.FirstName + " " + u.LastName
}).ToList();
// ไม่สามารถ Return จาก Method ได้ (Type ไร้ชื่อ)
// ต้อง Return IEnumerable หรือ Concrete Type
สรุป
| Approach | Implements Interface | Mutable | Scope | Use Case |
|---|---|---|---|---|
| Anonymous Type | ❌ | ❌ (Read-only) | Local Method | Projections, LINQ Results |
| Class/Struct | ✅ | ✅ | Anywhere | Domain Models, DTOs |
| Record (C# 9+) | ✅ | ❌ (Immutable) | Anywhere | Data Carriers, DTOs |
| ExpandoObject | ❌ | ✅ | Anywhere | Dynamic Data, Scripting |