特性 是附加在程式碼元素 (類、屬性、方法...) 上的宣告式中繼資料。編譯器將其編入組件元數據,運行時透過反射讀取,驅動序列化、驗證、ORM 映射、DI 容器等框架行為。
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class TableAttribute : Attribute
{
private string _tableName;
public TableAttribute() { }
public TableAttribute(string tableName) => _tableName = tableName;
public string TableName
{
get => _tableName;
set => _tableName = value;
}
}
AttributeTargets.Class:只能用於類;可用 Property、Method、All 等Inherited:子類是否繼承此特性AllowMultiple:同一目標是否可重複套用Attribute 結尾,使用時可省略 (如 [Table] 等同 [TableAttribute])[Table("Users")]
public class User
{
[Column("UserID", DbType = DbType.Int32)]
public int UserID { get; set; }
[Column("UserName", DbType = DbType.String)]
public string UserName { get; set; }
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ColumnAttribute : Attribute
{
public string ColumnName { get; set; }
public DbType DbType { get; set; }
public ColumnAttribute(string name) => ColumnName = name;
}
public class OrmHelper
{
public void Insert(object entity)
{
Type type = entity.GetType();
var tableAttr = type.GetCustomAttributes(typeof(TableAttribute), false)
.FirstOrDefault() as TableAttribute;
if (tableAttr == null) throw new InvalidOperationException("缺少 TableAttribute");
var sb = new StringBuilder($"INSERT INTO {tableAttr.TableName} (");
var props = type.GetProperties();
var columns = new List<string>();
var values = new List<string>();
foreach (var prop in props)
{
var colAttr = prop.GetCustomAttributes(typeof(ColumnAttribute), false)
.FirstOrDefault() as ColumnAttribute;
if (colAttr == null) continue; // 忽略無標記屬性
columns.Add(colAttr.ColumnName);
object val = prop.GetValue(entity);
values.Add(val == null ? "NULL" : FormatValue(val, colAttr.DbType));
}
sb.Append(string.Join(",", columns));
sb.Append(") VALUES (");
sb.Append(string.Join(",", values));
sb.Append(")");
Console.WriteLine(sb.ToString());
// 實際專案這裡執行 DbCommand
}
private string FormatValue(object val, DbType dbType)
{
return dbType == DbType.String ? $"'{val}'" : val.ToString();
}
}
var helper = new OrmHelper();
var user = new User { UserID = 1, UserName = "lfm" };
helper.Insert(user);
// 輸出: INSERT INTO Users (UserID,UserName) VALUES (1,'lfm')
[Column("Email", DbType = DbType.String)]
public string Email { get; set; }
// 等同於
[Column("Email")]
public string Email { get; set; } // DbType 走預設
| 特性 | 用途 | 命名空間 |
|---|---|---|
[Obsolete] | 標記過時成員 | System |
[Serializable] | 標記可序列化類型 | System |
[Conditional("DEBUG")] | 條件編譯方法 | System.Diagnostics |
[CallerMemberName] | 自動獲取調用者名稱 | System.Runtime.CompilerServices |
[Key] | EF 主鍵標記 | System.ComponentModel.DataAnnotations |
Inherited = true 讓基類特性自動流向子類AttributeTargets 防止誤用特性是框架與應用代碼的契約語言,掌握它能讓你讀懂主流框架源碼,也能打造屬於自己的微型框架。