Csharp反射与特性
csharp 反射
csharp 特性
- 特性语法就是用
方括号 [ ]给代码添加元数据,让编译器或框架根据这些标签执行额外行为.
using System;
using System.Reflection;
using System.Linq;
// 自定义特性1: 作者信息特性
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class AuthorAttribute : Attribute
{
public string Name { get; set; }
public string Date { get; set; }
public AuthorAttribute(string name, string date)
{
Name = name;
Date = date;
}
}
// 自定义特性2: 版本特性
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class VersionAttribute : Attribute
{
public string Version { get; set; }
public string? Description { get; set; }
public VersionAttribute(string version)
{
Version = version;
}
}
// 自定义特性3: 必填字段特性
[AttributeUsage(AttributeTargets.Property)]
public class RequiredAttribute : Attribute
{
public string ErrorMessage { get; set; }
public RequiredAttribute(string errorMessage = "此字段为必填项")
{
ErrorMessage = errorMessage;
}
}
// 使用特性的示例类
[Author("张三", "2026-01-16")]
[Version("1.0")]
[Version("1.1")] // 需要设置 AllowMultiple = true 才能多次使用
public class User
{
[Required("用户名不能为空")]
public string? Username { get; set; }
[Required("邮箱不能为空")]
public string? Email { get; set; }
public int Age { get; set; }
[Author("李四", "2026-01-15")]
public void PrintInfo()
{
Console.WriteLine($"用户名: {Username}, 邮箱: {Email}, 年龄: {Age}");
}
}
// 程序入口
class Program
{
static void Main(string[] args)
{
Console.OutputEncoding = System.Text.Encoding.UTF8;
Console.WriteLine("=== C# 特性(Attributes)示例程序 ===\n");
// 1. 读取类上的特性
Console.WriteLine("【1】读取 User 类上的特性:");
ReadClassAttributes(typeof(User));
Console.WriteLine("\n【2】读取属性上的特性:");
ReadPropertyAttributes(typeof(User));
Console.WriteLine("\n【3】读取方法上的特性:");
ReadMethodAttributes(typeof(User));
Console.WriteLine("\n【4】验证对象属性:");
ValidateObject();
Console.WriteLine("\n【5】使用内置特性示例:");
ShowBuiltInAttributes();
}
// 读取类上的特性
static void ReadClassAttributes(Type type)
{
// 读取 AuthorAttribute
var authorAttr = type.GetCustomAttribute<AuthorAttribute>();
if (authorAttr != null)
{
Console.WriteLine($" 作者: {authorAttr.Name}, 日期: {authorAttr.Date}");
}
// 读取 VersionAttribute(可能有多个)
var versionAttrs = type.GetCustomAttributes<VersionAttribute>();
foreach (var attr in versionAttrs)
{
Console.WriteLine($" 版本: {attr.Version}");
}
}
// 读取属性上的特性
static void ReadPropertyAttributes(Type type)
{
var properties = type.GetProperties();
foreach (var prop in properties)
{
var requiredAttr = prop.GetCustomAttribute<RequiredAttribute>();
if (requiredAttr != null)
{
Console.WriteLine($" 属性 '{prop.Name}': {requiredAttr.ErrorMessage}");
}
}
}
// 读取方法上的特性
static void ReadMethodAttributes(Type type)
{
var methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
foreach (var method in methods)
{
var authorAttr = method.GetCustomAttribute<AuthorAttribute>();
if (authorAttr != null)
{
Console.WriteLine($" 方法 '{method.Name}' - 作者: {authorAttr.Name}, 日期: {authorAttr.Date}");
}
}
}
// 验证对象(根据 Required 特性)
static void ValidateObject()
{
var user = new User { Username = "", Email = "[email protected]", Age = 25 };
var properties = typeof(User).GetProperties();
bool isValid = true;
foreach (var prop in properties)
{
var requiredAttr = prop.GetCustomAttribute<RequiredAttribute>();
if (requiredAttr != null)
{
var value = prop.GetValue(user);
if (value == null || (value is string && string.IsNullOrEmpty(value.ToString())))
{
Console.WriteLine($" ✗ 验证失败: {requiredAttr.ErrorMessage}");
isValid = false;
}
else
{
Console.WriteLine($" ✓ {prop.Name} 验证通过");
}
}
}
Console.WriteLine($"\n 整体验证结果: {(isValid ? "通过" : "失败")}");
}
// 演示内置特性
static void ShowBuiltInAttributes()
{
var type = typeof(User);
// Obsolete 特性示例
Console.WriteLine($" 类型 '{type.Name}' 完全限定名: {type.FullName}");
Console.WriteLine($" 程序集: {type.Assembly.GetName().Name}");
// 检查是否标记了 Serializable
var isSerializable = type.GetCustomAttribute<SerializableAttribute>() != null;
Console.WriteLine($" 是否可序列化: {isSerializable}");
}
}
// === C# 特性(Attributes)示例程序 ===
// 【1】读取 User 类上的特性:
// 作者: 张三, 日期: 2026-01-16
// 版本: 1.0
// 版本: 1.1
// 【2】读取属性上的特性:
// 属性 'Username': 用户名不能为空
// 属性 'Email': 邮箱不能为空
// 【3】读取方法上的特性:
// 方法 'PrintInfo' - 作者: 李四, 日期: 2026-01-15
// 【4】验证对象属性:
// ✗ 验证失败: 用户名不能为空
// ✓ Email 验证通过
// 整体验证结果: 失败
// 【5】使用内置特性示例:
// 类型 'User' 完全限定名: User
// 程序集: TestApp
// 是否可序列化: False
参考链接
1.C#反射