本章概述
反射(Reflection)和特性(Attributes)是C#中强大的元编程特性,它们允许程序在运行时检查、分析和操作类型信息。反射提供了在运行时获取类型信息、创建对象实例、调用方法和访问属性的能力,而特性则允许我们为代码元素添加元数据,实现声明式编程。
学习目标
通过本章学习,你将能够: - 理解反射的概念和应用场景 - 掌握Type类和反射API的使用 - 学会创建和使用自定义特性 - 了解内置特性的功能和用法 - 掌握动态类型创建和代码生成 - 理解反射的性能影响和优化策略
1. 反射基础
1.1 反射概念和Type类
using System;
using System.Reflection;
using System.Linq;
public class ReflectionBasics
{
public static void DemonstrateReflectionBasics()
{
Console.WriteLine("=== 反射基础演示 ===");
Console.WriteLine("\n--- 获取Type对象的方式 ---");
DemonstrateGettingTypes();
Console.WriteLine("\n--- Type类的基本信息 ---");
DemonstrateTypeInformation();
Console.WriteLine("\n--- 泛型类型信息 ---");
DemonstrateGenericTypes();
}
private static void DemonstrateGettingTypes()
{
// 方式1: 使用typeof操作符
Type stringType1 = typeof(string);
Console.WriteLine($"typeof(string): {stringType1.Name}");
// 方式2: 使用对象的GetType()方法
string text = "Hello";
Type stringType2 = text.GetType();
Console.WriteLine($"\"Hello\".GetType(): {stringType2.Name}");
// 方式3: 使用Type.GetType()方法
Type stringType3 = Type.GetType("System.String");
Console.WriteLine($"Type.GetType(\"System.String\"): {stringType3?.Name}");
// 方式4: 从程序集获取
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] types = assembly.GetTypes();
Console.WriteLine($"当前程序集包含 {types.Length} 个类型");
// 检查类型相等性
Console.WriteLine($"三种方式获取的Type是否相等: {stringType1 == stringType2 && stringType2 == stringType3}");
}
private static void DemonstrateTypeInformation()
{
Type personType = typeof(Person);
Console.WriteLine($"类型名称: {personType.Name}");
Console.WriteLine($"完全限定名: {personType.FullName}");
Console.WriteLine($"命名空间: {personType.Namespace}");
Console.WriteLine($"程序集: {personType.Assembly.GetName().Name}");
Console.WriteLine($"是否为类: {personType.IsClass}");
Console.WriteLine($"是否为接口: {personType.IsInterface}");
Console.WriteLine($"是否为值类型: {personType.IsValueType}");
Console.WriteLine($"是否为枚举: {personType.IsEnum}");
Console.WriteLine($"是否为抽象类: {personType.IsAbstract}");
Console.WriteLine($"是否为密封类: {personType.IsSealed}");
Console.WriteLine($"是否为泛型: {personType.IsGenericType}");
Console.WriteLine($"是否为泛型定义: {personType.IsGenericTypeDefinition}");
// 基类和接口信息
Console.WriteLine($"基类: {personType.BaseType?.Name}");
Type[] interfaces = personType.GetInterfaces();
Console.WriteLine($"实现的接口: {string.Join(", ", interfaces.Select(i => i.Name))}");
}
private static void DemonstrateGenericTypes()
{
// 泛型类型定义
Type listDefinition = typeof(List<>);
Console.WriteLine($"泛型定义: {listDefinition.Name}");
Console.WriteLine($"是否为泛型定义: {listDefinition.IsGenericTypeDefinition}");
// 构造的泛型类型
Type listOfString = typeof(List<string>);
Console.WriteLine($"构造的泛型类型: {listOfString.Name}");
Console.WriteLine($"是否为泛型类型: {listOfString.IsGenericType}");
Console.WriteLine($"是否为泛型定义: {listOfString.IsGenericTypeDefinition}");
// 获取泛型参数
Type[] genericArguments = listOfString.GetGenericArguments();
Console.WriteLine($"泛型参数: {string.Join(", ", genericArguments.Select(t => t.Name))}");
// 获取泛型定义
Type genericDefinition = listOfString.GetGenericTypeDefinition();
Console.WriteLine($"泛型定义: {genericDefinition.Name}");
// 构造泛型类型
Type listOfInt = listDefinition.MakeGenericType(typeof(int));
Console.WriteLine($"动态构造的泛型类型: {listOfInt.Name}");
}
}
// 示例类
public class Person : IComparable<Person>
{
public string Name { get; set; }
public int Age { get; set; }
public DateTime BirthDate { get; set; }
public Person() { }
public Person(string name, int age)
{
Name = name;
Age = age;
}
public void SayHello()
{
Console.WriteLine($"Hello, I'm {Name}");
}
public string GetInfo()
{
return $"Name: {Name}, Age: {Age}";
}
public int CompareTo(Person other)
{
return Age.CompareTo(other?.Age ?? 0);
}
public override string ToString()
{
return $"Person(Name={Name}, Age={Age})";
}
}
4. 反射性能优化
4.1 反射性能分析和缓存策略
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Linq.Expressions;
public class ReflectionPerformanceDemo
{
private static readonly ConcurrentDictionary<string, MethodInfo> _methodCache = new();
private static readonly ConcurrentDictionary<Type, PropertyInfo[]> _propertyCache = new();
private static readonly ConcurrentDictionary<string, Func<object, object[], object>> _compiledMethods = new();
public static void DemonstratePerformanceOptimization()
{
Console.WriteLine("\n=== 反射性能优化演示 ===");
Console.WriteLine("\n--- 性能对比测试 ---");
PerformanceComparison();
Console.WriteLine("\n--- 缓存策略演示 ---");
DemonstrateCaching();
Console.WriteLine("\n--- 委托编译优化 ---");
DemonstrateDelegateCompilation();
}
private static void PerformanceComparison()
{
const int iterations = 100000;
var person = new Person("测试", 25);
// 直接调用
var sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
string result = person.GetInfo();
}
sw.Stop();
Console.WriteLine($"直接调用 {iterations} 次: {sw.ElapsedMilliseconds}ms");
// 反射调用(无缓存)
sw.Restart();
for (int i = 0; i < iterations; i++)
{
Type type = person.GetType();
MethodInfo method = type.GetMethod("GetInfo");
object result = method?.Invoke(person, null);
}
sw.Stop();
Console.WriteLine($"反射调用(无缓存) {iterations} 次: {sw.ElapsedMilliseconds}ms");
// 反射调用(有缓存)
sw.Restart();
MethodInfo cachedMethod = typeof(Person).GetMethod("GetInfo");
for (int i = 0; i < iterations; i++)
{
object result = cachedMethod?.Invoke(person, null);
}
sw.Stop();
Console.WriteLine($"反射调用(有缓存) {iterations} 次: {sw.ElapsedMilliseconds}ms");
// 编译委托调用
sw.Restart();
var compiledDelegate = CreateCompiledDelegate<Person, string>("GetInfo");
for (int i = 0; i < iterations; i++)
{
string result = compiledDelegate(person);
}
sw.Stop();
Console.WriteLine($"编译委托调用 {iterations} 次: {sw.ElapsedMilliseconds}ms");
}
private static void DemonstrateCaching()
{
// 方法缓存
MethodInfo method1 = GetCachedMethod(typeof(Person), "GetInfo");
MethodInfo method2 = GetCachedMethod(typeof(Person), "GetInfo");
Console.WriteLine($"方法缓存命中: {ReferenceEquals(method1, method2)}");
// 属性缓存
PropertyInfo[] props1 = GetCachedProperties(typeof(Person));
PropertyInfo[] props2 = GetCachedProperties(typeof(Person));
Console.WriteLine($"属性缓存命中: {ReferenceEquals(props1, props2)}");
// 显示缓存统计
Console.WriteLine($"方法缓存大小: {_methodCache.Count}");
Console.WriteLine($"属性缓存大小: {_propertyCache.Count}");
}
private static void DemonstrateDelegateCompilation()
{
var person = new Person("张三", 30);
// 编译方法调用委托
var getInfoDelegate = GetOrCreateCompiledMethod(typeof(Person), "GetInfo");
object result = getInfoDelegate(person, new object[0]);
Console.WriteLine($"编译委托调用结果: {result}");
// 编译属性访问委托
var getNameDelegate = CreatePropertyGetter<Person, string>("Name");
string name = getNameDelegate(person);
Console.WriteLine($"编译属性访问结果: {name}");
var setNameDelegate = CreatePropertySetter<Person, string>("Name");
setNameDelegate(person, "李四");
Console.WriteLine($"设置属性后: {person.Name}");
}
// 缓存辅助方法
private static MethodInfo GetCachedMethod(Type type, string methodName)
{
string key = $"{type.FullName}.{methodName}";
return _methodCache.GetOrAdd(key, _ => type.GetMethod(methodName));
}
private static PropertyInfo[] GetCachedProperties(Type type)
{
return _propertyCache.GetOrAdd(type, t => t.GetProperties());
}
private static Func<object, object[], object> GetOrCreateCompiledMethod(Type type, string methodName)
{
string key = $"{type.FullName}.{methodName}";
return _compiledMethods.GetOrAdd(key, _ => CompileMethod(type, methodName));
}
// 编译方法委托
private static Func<object, object[], object> CompileMethod(Type type, string methodName)
{
MethodInfo method = type.GetMethod(methodName);
if (method == null) return null;
var instanceParam = Expression.Parameter(typeof(object), "instance");
var argsParam = Expression.Parameter(typeof(object[]), "args");
var instanceCast = Expression.Convert(instanceParam, type);
ParameterInfo[] parameters = method.GetParameters();
Expression[] argExpressions = new Expression[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
var argAccess = Expression.ArrayIndex(argsParam, Expression.Constant(i));
argExpressions[i] = Expression.Convert(argAccess, parameters[i].ParameterType);
}
var methodCall = Expression.Call(instanceCast, method, argExpressions);
Expression body;
if (method.ReturnType == typeof(void))
{
body = Expression.Block(methodCall, Expression.Constant(null));
}
else
{
body = Expression.Convert(methodCall, typeof(object));
}
var lambda = Expression.Lambda<Func<object, object[], object>>(body, instanceParam, argsParam);
return lambda.Compile();
}
// 编译属性访问委托
private static Func<T, TProperty> CreatePropertyGetter<T, TProperty>(string propertyName)
{
var parameter = Expression.Parameter(typeof(T), "obj");
var property = Expression.Property(parameter, propertyName);
var lambda = Expression.Lambda<Func<T, TProperty>>(property, parameter);
return lambda.Compile();
}
private static Action<T, TProperty> CreatePropertySetter<T, TProperty>(string propertyName)
{
var objParam = Expression.Parameter(typeof(T), "obj");
var valueParam = Expression.Parameter(typeof(TProperty), "value");
var property = Expression.Property(objParam, propertyName);
var assign = Expression.Assign(property, valueParam);
var lambda = Expression.Lambda<Action<T, TProperty>>(assign, objParam, valueParam);
return lambda.Compile();
}
// 泛型编译委托
private static Func<T, TResult> CreateCompiledDelegate<T, TResult>(string methodName)
{
var parameter = Expression.Parameter(typeof(T), "obj");
var method = typeof(T).GetMethod(methodName);
var methodCall = Expression.Call(parameter, method);
var lambda = Expression.Lambda<Func<T, TResult>>(methodCall, parameter);
return lambda.Compile();
}
}
4.2 表达式树和动态代码生成
using System.Linq.Expressions;
using System.Reflection.Emit;
public class ExpressionTreeDemo
{
public static void DemonstrateExpressionTrees()
{
Console.WriteLine("\n=== 表达式树演示 ===");
Console.WriteLine("\n--- 基础表达式树 ---");
DemonstrateBasicExpressions();
Console.WriteLine("\n--- 动态查询构建 ---");
DemonstrateDynamicQueries();
Console.WriteLine("\n--- 动态方法生成 ---");
DemonstrateDynamicMethods();
}
private static void DemonstrateBasicExpressions()
{
// 创建简单的数学表达式: (x, y) => x + y * 2
var xParam = Expression.Parameter(typeof(int), "x");
var yParam = Expression.Parameter(typeof(int), "y");
var multiply = Expression.Multiply(yParam, Expression.Constant(2));
var add = Expression.Add(xParam, multiply);
var lambda = Expression.Lambda<Func<int, int, int>>(add, xParam, yParam);
var compiled = lambda.Compile();
Console.WriteLine($"表达式: {lambda}");
Console.WriteLine($"计算结果 (3, 4): {compiled(3, 4)}");
// 创建条件表达式: x > 10 ? "大" : "小"
var condition = Expression.GreaterThan(xParam, Expression.Constant(10));
var conditional = Expression.Condition(
condition,
Expression.Constant("大"),
Expression.Constant("小")
);
var conditionalLambda = Expression.Lambda<Func<int, string>>(conditional, xParam);
var conditionalCompiled = conditionalLambda.Compile();
Console.WriteLine($"条件表达式: {conditionalLambda}");
Console.WriteLine($"结果 (15): {conditionalCompiled(15)}");
Console.WriteLine($"结果 (5): {conditionalCompiled(5)}");
}
private static void DemonstrateDynamicQueries()
{
var people = new List<Person>
{
new Person("张三", 25),
new Person("李四", 30),
new Person("王五", 35),
new Person("赵六", 20)
};
// 动态构建查询条件
var queryBuilder = new DynamicQueryBuilder<Person>();
// 年龄大于25的人
var ageFilter = queryBuilder.CreateFilter("Age", ">=", 25);
var filteredByAge = people.AsQueryable().Where(ageFilter).ToList();
Console.WriteLine($"年龄>=25的人: {string.Join(", ", filteredByAge.Select(p => p.Name))}");
// 姓名包含"三"的人
var nameFilter = queryBuilder.CreateStringFilter("Name", "Contains", "三");
var filteredByName = people.AsQueryable().Where(nameFilter).ToList();
Console.WriteLine($"姓名包含'三'的人: {string.Join(", ", filteredByName.Select(p => p.Name))}");
// 组合条件:年龄>20 且 姓名长度=2
var combinedFilter = queryBuilder.CreateCombinedFilter(
queryBuilder.CreateFilter("Age", ">", 20),
queryBuilder.CreateFilter("Name.Length", "==", 2)
);
var filteredByCombined = people.AsQueryable().Where(combinedFilter).ToList();
Console.WriteLine($"年龄>20且姓名长度=2的人: {string.Join(", ", filteredByCombined.Select(p => p.Name))}");
}
private static void DemonstrateDynamicMethods()
{
// 使用Emit动态生成方法
var calculator = CreateDynamicCalculator();
int result1 = calculator(10, 5, "+");
int result2 = calculator(10, 5, "-");
int result3 = calculator(10, 5, "*");
int result4 = calculator(10, 5, "/");
Console.WriteLine($"动态计算器结果:");
Console.WriteLine($" 10 + 5 = {result1}");
Console.WriteLine($" 10 - 5 = {result2}");
Console.WriteLine($" 10 * 5 = {result3}");
Console.WriteLine($" 10 / 5 = {result4}");
}
private static Func<int, int, string, int> CreateDynamicCalculator()
{
var method = new DynamicMethod(
"Calculate",
typeof(int),
new[] { typeof(int), typeof(int), typeof(string) },
typeof(ExpressionTreeDemo)
);
ILGenerator il = method.GetILGenerator();
// 定义标签
Label addLabel = il.DefineLabel();
Label subLabel = il.DefineLabel();
Label mulLabel = il.DefineLabel();
Label divLabel = il.DefineLabel();
Label endLabel = il.DefineLabel();
// 加载操作符参数
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Ldstr, "+");
il.Emit(OpCodes.Call, typeof(string).GetMethod("op_Equality", new[] { typeof(string), typeof(string) }));
il.Emit(OpCodes.Brtrue, addLabel);
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Ldstr, "-");
il.Emit(OpCodes.Call, typeof(string).GetMethod("op_Equality", new[] { typeof(string), typeof(string) }));
il.Emit(OpCodes.Brtrue, subLabel);
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Ldstr, "*");
il.Emit(OpCodes.Call, typeof(string).GetMethod("op_Equality", new[] { typeof(string), typeof(string) }));
il.Emit(OpCodes.Brtrue, mulLabel);
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Ldstr, "/");
il.Emit(OpCodes.Call, typeof(string).GetMethod("op_Equality", new[] { typeof(string), typeof(string) }));
il.Emit(OpCodes.Brtrue, divLabel);
// 默认返回0
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Br, endLabel);
// 加法
il.MarkLabel(addLabel);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Br, endLabel);
// 减法
il.MarkLabel(subLabel);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Sub);
il.Emit(OpCodes.Br, endLabel);
// 乘法
il.MarkLabel(mulLabel);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Mul);
il.Emit(OpCodes.Br, endLabel);
// 除法
il.MarkLabel(divLabel);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Div);
il.MarkLabel(endLabel);
il.Emit(OpCodes.Ret);
return (Func<int, int, string, int>)method.CreateDelegate(typeof(Func<int, int, string, int>));
}
}
// 动态查询构建器
public class DynamicQueryBuilder<T>
{
public Expression<Func<T, bool>> CreateFilter(string propertyName, string operation, object value)
{
var parameter = Expression.Parameter(typeof(T), "x");
var property = GetPropertyExpression(parameter, propertyName);
var constant = Expression.Constant(value);
BinaryExpression comparison = operation switch
{
"==" => Expression.Equal(property, constant),
"!=" => Expression.NotEqual(property, constant),
">" => Expression.GreaterThan(property, constant),
">=" => Expression.GreaterThanOrEqual(property, constant),
"<" => Expression.LessThan(property, constant),
"<=" => Expression.LessThanOrEqual(property, constant),
_ => throw new ArgumentException($"不支持的操作: {operation}")
};
return Expression.Lambda<Func<T, bool>>(comparison, parameter);
}
public Expression<Func<T, bool>> CreateStringFilter(string propertyName, string operation, string value)
{
var parameter = Expression.Parameter(typeof(T), "x");
var property = GetPropertyExpression(parameter, propertyName);
var constant = Expression.Constant(value);
MethodCallExpression methodCall = operation switch
{
"Contains" => Expression.Call(property, typeof(string).GetMethod("Contains", new[] { typeof(string) }), constant),
"StartsWith" => Expression.Call(property, typeof(string).GetMethod("StartsWith", new[] { typeof(string) }), constant),
"EndsWith" => Expression.Call(property, typeof(string).GetMethod("EndsWith", new[] { typeof(string) }), constant),
_ => throw new ArgumentException($"不支持的字符串操作: {operation}")
};
return Expression.Lambda<Func<T, bool>>(methodCall, parameter);
}
public Expression<Func<T, bool>> CreateCombinedFilter(
Expression<Func<T, bool>> left,
Expression<Func<T, bool>> right,
string logicalOperator = "AND")
{
var parameter = Expression.Parameter(typeof(T), "x");
var leftBody = ReplaceParameter(left.Body, left.Parameters[0], parameter);
var rightBody = ReplaceParameter(right.Body, right.Parameters[0], parameter);
BinaryExpression combined = logicalOperator.ToUpper() switch
{
"AND" => Expression.AndAlso(leftBody, rightBody),
"OR" => Expression.OrElse(leftBody, rightBody),
_ => throw new ArgumentException($"不支持的逻辑操作: {logicalOperator}")
};
return Expression.Lambda<Func<T, bool>>(combined, parameter);
}
private Expression GetPropertyExpression(Expression parameter, string propertyPath)
{
Expression property = parameter;
foreach (string propertyName in propertyPath.Split('.'))
{
property = Expression.Property(property, propertyName);
}
return property;
}
private Expression ReplaceParameter(Expression expression, ParameterExpression oldParameter, ParameterExpression newParameter)
{
return new ParameterReplacer(oldParameter, newParameter).Visit(expression);
}
private class ParameterReplacer : ExpressionVisitor
{
private readonly ParameterExpression _oldParameter;
private readonly ParameterExpression _newParameter;
public ParameterReplacer(ParameterExpression oldParameter, ParameterExpression newParameter)
{
_oldParameter = oldParameter;
_newParameter = newParameter;
}
protected override Expression VisitParameter(ParameterExpression node)
{
return node == _oldParameter ? _newParameter : base.VisitParameter(node);
}
}
}
5. 实践应用
5.1 对象映射器
public class ObjectMapper
{
private static readonly ConcurrentDictionary<string, Func<object, object>> _mapperCache = new();
public static TTarget Map<TSource, TTarget>(TSource source) where TTarget : new()
{
if (source == null) return default(TTarget);
string cacheKey = $"{typeof(TSource).FullName}_to_{typeof(TTarget).FullName}";
var mapper = _mapperCache.GetOrAdd(cacheKey, _ => CreateMapper<TSource, TTarget>());
return (TTarget)mapper(source);
}
private static Func<object, object> CreateMapper<TSource, TTarget>() where TTarget : new()
{
var sourceType = typeof(TSource);
var targetType = typeof(TTarget);
var sourceParam = Expression.Parameter(typeof(object), "source");
var sourceCast = Expression.Convert(sourceParam, sourceType);
var targetVar = Expression.Variable(targetType, "target");
var targetAssign = Expression.Assign(targetVar, Expression.New(targetType));
var expressions = new List<Expression> { targetAssign };
var sourceProperties = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanRead)
.ToDictionary(p => p.Name, p => p);
var targetProperties = targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanWrite);
foreach (var targetProp in targetProperties)
{
if (sourceProperties.TryGetValue(targetProp.Name, out var sourceProp))
{
if (IsCompatibleType(sourceProp.PropertyType, targetProp.PropertyType))
{
var sourceValue = Expression.Property(sourceCast, sourceProp);
var targetProperty = Expression.Property(targetVar, targetProp);
Expression valueExpression = sourceValue;
if (sourceProp.PropertyType != targetProp.PropertyType)
{
valueExpression = Expression.Convert(sourceValue, targetProp.PropertyType);
}
var assignment = Expression.Assign(targetProperty, valueExpression);
expressions.Add(assignment);
}
}
}
expressions.Add(Expression.Convert(targetVar, typeof(object)));
var block = Expression.Block(new[] { targetVar }, expressions);
var lambda = Expression.Lambda<Func<object, object>>(block, sourceParam);
return lambda.Compile();
}
private static bool IsCompatibleType(Type sourceType, Type targetType)
{
if (sourceType == targetType) return true;
if (targetType.IsAssignableFrom(sourceType)) return true;
// 检查可空类型
var sourceUnderlyingType = Nullable.GetUnderlyingType(sourceType);
var targetUnderlyingType = Nullable.GetUnderlyingType(targetType);
if (sourceUnderlyingType != null && targetUnderlyingType != null)
{
return sourceUnderlyingType == targetUnderlyingType;
}
if (sourceUnderlyingType != null)
{
return sourceUnderlyingType == targetType;
}
if (targetUnderlyingType != null)
{
return sourceType == targetUnderlyingType;
}
// 检查数值类型转换
return IsNumericType(sourceType) && IsNumericType(targetType);
}
private static bool IsNumericType(Type type)
{
return type == typeof(byte) || type == typeof(sbyte) ||
type == typeof(short) || type == typeof(ushort) ||
type == typeof(int) || type == typeof(uint) ||
type == typeof(long) || type == typeof(ulong) ||
type == typeof(float) || type == typeof(double) ||
type == typeof(decimal);
}
}
// 示例DTO类
public class PersonDto
{
public string Name { get; set; }
public int Age { get; set; }
public DateTime? BirthDate { get; set; }
}
public class PersonViewModel
{
public string Name { get; set; }
public int Age { get; set; }
public string BirthDate { get; set; }
public string DisplayName { get; set; }
}
public class ObjectMapperDemo
{
public static void DemonstrateObjectMapping()
{
Console.WriteLine("\n=== 对象映射演示 ===");
var personDto = new PersonDto
{
Name = "张三",
Age = 25,
BirthDate = new DateTime(1998, 5, 15)
};
Console.WriteLine($"源对象: Name={personDto.Name}, Age={personDto.Age}, BirthDate={personDto.BirthDate}");
// 映射到Person
var person = ObjectMapper.Map<PersonDto, Person>(personDto);
Console.WriteLine($"映射到Person: {person}");
// 映射到ViewModel
var viewModel = ObjectMapper.Map<PersonDto, PersonViewModel>(personDto);
Console.WriteLine($"映射到ViewModel: Name={viewModel.Name}, Age={viewModel.Age}, BirthDate={viewModel.BirthDate}");
// 性能测试
const int iterations = 100000;
var sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
var mapped = ObjectMapper.Map<PersonDto, Person>(personDto);
}
sw.Stop();
Console.WriteLine($"映射 {iterations} 次耗时: {sw.ElapsedMilliseconds}ms");
}
}
5.2 配置绑定系统
public class ConfigurationBinder
{
private static readonly ConcurrentDictionary<Type, Action<object, Dictionary<string, object>>> _binderCache = new();
public static T Bind<T>(Dictionary<string, object> configuration) where T : new()
{
var instance = new T();
Bind(instance, configuration);
return instance;
}
public static void Bind<T>(T instance, Dictionary<string, object> configuration)
{
if (instance == null || configuration == null) return;
var type = typeof(T);
var binder = _binderCache.GetOrAdd(type, CreateBinder);
binder(instance, configuration);
}
private static Action<object, Dictionary<string, object>> CreateBinder(Type type)
{
var instanceParam = Expression.Parameter(typeof(object), "instance");
var configParam = Expression.Parameter(typeof(Dictionary<string, object>), "config");
var instanceCast = Expression.Convert(instanceParam, type);
var expressions = new List<Expression>();
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanWrite);
foreach (var property in properties)
{
var configAttribute = property.GetCustomAttribute<ConfigurationKeyAttribute>();
var configKey = configAttribute?.Key ?? property.Name;
// 检查配置中是否存在该键
var containsKeyMethod = typeof(Dictionary<string, object>).GetMethod("ContainsKey");
var containsKey = Expression.Call(configParam, containsKeyMethod, Expression.Constant(configKey));
// 获取配置值
var indexer = typeof(Dictionary<string, object>).GetProperty("Item");
var configValue = Expression.Property(configParam, indexer, Expression.Constant(configKey));
// 转换并赋值
var propertyAccess = Expression.Property(instanceCast, property);
var convertedValue = CreateValueConverter(configValue, property.PropertyType);
var assignment = Expression.Assign(propertyAccess, convertedValue);
// 条件赋值(只有当配置中存在该键时才赋值)
var conditionalAssignment = Expression.IfThen(containsKey, assignment);
expressions.Add(conditionalAssignment);
}
var block = Expression.Block(expressions);
var lambda = Expression.Lambda<Action<object, Dictionary<string, object>>>(block, instanceParam, configParam);
return lambda.Compile();
}
private static Expression CreateValueConverter(Expression configValue, Type targetType)
{
// 如果目标类型是object,直接返回
if (targetType == typeof(object))
{
return configValue;
}
// 如果是可空类型,获取底层类型
var underlyingType = Nullable.GetUnderlyingType(targetType);
var actualTargetType = underlyingType ?? targetType;
// 创建转换表达式
var convertMethod = typeof(Convert).GetMethod($"To{actualTargetType.Name}", new[] { typeof(object) });
if (convertMethod != null)
{
var converted = Expression.Call(convertMethod, configValue);
if (underlyingType != null)
{
// 可空类型,需要额外处理
return Expression.Convert(converted, targetType);
}
return converted;
}
// 如果是字符串类型
if (actualTargetType == typeof(string))
{
var toStringMethod = typeof(object).GetMethod("ToString");
return Expression.Call(configValue, toStringMethod);
}
// 如果是枚举类型
if (actualTargetType.IsEnum)
{
var parseMethod = typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(string) });
var toString = Expression.Call(configValue, typeof(object).GetMethod("ToString"));
var enumParse = Expression.Call(parseMethod, Expression.Constant(actualTargetType), toString);
return Expression.Convert(enumParse, targetType);
}
// 默认转换
return Expression.Convert(configValue, targetType);
}
}
// 配置键特性
[AttributeUsage(AttributeTargets.Property)]
public class ConfigurationKeyAttribute : Attribute
{
public string Key { get; }
public ConfigurationKeyAttribute(string key)
{
Key = key;
}
}
// 示例配置类
public class DatabaseConfiguration
{
[ConfigurationKey("db_host")]
public string Host { get; set; }
[ConfigurationKey("db_port")]
public int Port { get; set; }
public string Database { get; set; }
public string Username { get; set; }
public string Password { get; set; }
[ConfigurationKey("connection_timeout")]
public int? ConnectionTimeout { get; set; }
public bool EnableSsl { get; set; }
}
public enum LogLevel
{
Debug,
Info,
Warning,
Error
}
public class LoggingConfiguration
{
public LogLevel Level { get; set; }
public string OutputPath { get; set; }
public int MaxFileSize { get; set; }
public bool EnableConsole { get; set; }
}
public class ConfigurationBinderDemo
{
public static void DemonstrateConfigurationBinding()
{
Console.WriteLine("\n=== 配置绑定演示 ===");
// 模拟配置数据
var databaseConfig = new Dictionary<string, object>
{
{ "db_host", "localhost" },
{ "db_port", 5432 },
{ "Database", "myapp" },
{ "Username", "admin" },
{ "Password", "secret" },
{ "connection_timeout", 30 },
{ "EnableSsl", true }
};
var loggingConfig = new Dictionary<string, object>
{
{ "Level", "Info" },
{ "OutputPath", "/var/log/app.log" },
{ "MaxFileSize", 10485760 }, // 10MB
{ "EnableConsole", false }
};
// 绑定配置
var dbConfig = ConfigurationBinder.Bind<DatabaseConfiguration>(databaseConfig);
var logConfig = ConfigurationBinder.Bind<LoggingConfiguration>(loggingConfig);
Console.WriteLine("数据库配置:");
Console.WriteLine($" 主机: {dbConfig.Host}");
Console.WriteLine($" 端口: {dbConfig.Port}");
Console.WriteLine($" 数据库: {dbConfig.Database}");
Console.WriteLine($" 用户名: {dbConfig.Username}");
Console.WriteLine($" 连接超时: {dbConfig.ConnectionTimeout}");
Console.WriteLine($" 启用SSL: {dbConfig.EnableSsl}");
Console.WriteLine("\n日志配置:");
Console.WriteLine($" 级别: {logConfig.Level}");
Console.WriteLine($" 输出路径: {logConfig.OutputPath}");
Console.WriteLine($" 最大文件大小: {logConfig.MaxFileSize}");
Console.WriteLine($" 启用控制台: {logConfig.EnableConsole}");
// 性能测试
const int iterations = 10000;
var sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
var config = ConfigurationBinder.Bind<DatabaseConfiguration>(databaseConfig);
}
sw.Stop();
Console.WriteLine($"\n绑定 {iterations} 次耗时: {sw.ElapsedMilliseconds}ms");
}
}
6. 最佳实践和注意事项
6.1 反射最佳实践
public class ReflectionBestPractices
{
public static void DemonstrateBestPractices()
{
Console.WriteLine("\n=== 反射最佳实践演示 ===");
Console.WriteLine("\n--- 缓存反射信息 ---");
DemonstrateCaching();
Console.WriteLine("\n--- 异常处理 ---");
DemonstrateExceptionHandling();
Console.WriteLine("\n--- 性能考虑 ---");
DemonstratePerformanceConsiderations();
Console.WriteLine("\n--- 安全性考虑 ---");
DemonstrateSecurityConsiderations();
}
private static void DemonstrateCaching()
{
// 好的做法:缓存反射信息
var typeCache = new Dictionary<string, Type>();
var methodCache = new Dictionary<string, MethodInfo>();
// 缓存类型信息
string typeName = "System.String";
if (!typeCache.TryGetValue(typeName, out Type cachedType))
{
cachedType = Type.GetType(typeName);
typeCache[typeName] = cachedType;
}
// 缓存方法信息
string methodKey = $"{cachedType.FullName}.Substring";
if (!methodCache.TryGetValue(methodKey, out MethodInfo cachedMethod))
{
cachedMethod = cachedType.GetMethod("Substring", new[] { typeof(int), typeof(int) });
methodCache[methodKey] = cachedMethod;
}
Console.WriteLine($"缓存的类型: {cachedType.Name}");
Console.WriteLine($"缓存的方法: {cachedMethod.Name}");
}
private static void DemonstrateExceptionHandling()
{
try
{
// 安全的反射调用
Type type = typeof(string);
MethodInfo method = type.GetMethod("NonExistentMethod");
if (method != null)
{
object result = method.Invoke("test", null);
}
else
{
Console.WriteLine("方法不存在,避免了异常");
}
}
catch (TargetInvocationException ex)
{
// 处理目标方法抛出的异常
Console.WriteLine($"目标方法异常: {ex.InnerException?.Message}");
}
catch (ArgumentException ex)
{
// 处理参数异常
Console.WriteLine($"参数异常: {ex.Message}");
}
catch (TargetParameterCountException ex)
{
// 处理参数数量异常
Console.WriteLine($"参数数量异常: {ex.Message}");
}
}
private static void DemonstratePerformanceConsiderations()
{
const int iterations = 10000;
// 避免在循环中重复获取反射信息
Type stringType = typeof(string);
MethodInfo substringMethod = stringType.GetMethod("Substring", new[] { typeof(int), typeof(int) });
var sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
// 好的做法:重用缓存的反射信息
object result = substringMethod.Invoke("Hello World", new object[] { 0, 5 });
}
sw.Stop();
Console.WriteLine($"重用反射信息 {iterations} 次: {sw.ElapsedMilliseconds}ms");
// 对比:每次都获取反射信息(不推荐)
sw.Restart();
for (int i = 0; i < iterations; i++)
{
// 坏的做法:每次都获取反射信息
Type type = typeof(string);
MethodInfo method = type.GetMethod("Substring", new[] { typeof(int), typeof(int) });
object result = method.Invoke("Hello World", new object[] { 0, 5 });
}
sw.Stop();
Console.WriteLine($"重复获取反射信息 {iterations} 次: {sw.ElapsedMilliseconds}ms");
}
private static void DemonstrateSecurityConsiderations()
{
// 验证类型安全
string typeName = "System.String"; // 来自用户输入
// 好的做法:验证类型名称
if (IsAllowedType(typeName))
{
Type type = Type.GetType(typeName);
Console.WriteLine($"允许的类型: {type?.Name}");
}
else
{
Console.WriteLine($"不允许的类型: {typeName}");
}
// 验证程序集来源
Type stringType = typeof(string);
if (IsTrustedAssembly(stringType.Assembly))
{
Console.WriteLine($"来自受信任程序集: {stringType.Assembly.GetName().Name}");
}
}
private static bool IsAllowedType(string typeName)
{
// 白名单验证
var allowedTypes = new HashSet<string>
{
"System.String",
"System.Int32",
"System.DateTime",
// 添加其他允许的类型
};
return allowedTypes.Contains(typeName);
}
private static bool IsTrustedAssembly(Assembly assembly)
{
// 验证程序集是否来自受信任的位置
var trustedAssemblies = new HashSet<string>
{
"mscorlib",
"System.Core",
"System.Private.CoreLib",
// 添加其他受信任的程序集
};
return trustedAssemblies.Contains(assembly.GetName().Name);
}
}
6.2 特性设计原则
// 好的特性设计示例
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class ValidationAttribute : Attribute
{
public string ErrorMessage { get; set; }
public bool IsRequired { get; set; }
protected ValidationAttribute()
{
ErrorMessage = "验证失败";
}
public virtual bool IsValid(object value)
{
if (IsRequired && value == null)
{
return false;
}
return ValidateValue(value);
}
protected virtual bool ValidateValue(object value)
{
return true; // 基类默认验证通过
}
}
[AttributeUsage(AttributeTargets.Property)]
public class RangeAttribute : ValidationAttribute
{
public double Minimum { get; }
public double Maximum { get; }
public RangeAttribute(double minimum, double maximum)
{
Minimum = minimum;
Maximum = maximum;
ErrorMessage = $"值必须在 {minimum} 到 {maximum} 之间";
}
protected override bool ValidateValue(object value)
{
if (value == null) return !IsRequired;
if (double.TryParse(value.ToString(), out double numericValue))
{
return numericValue >= Minimum && numericValue <= Maximum;
}
return false;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class StringLengthAttribute : ValidationAttribute
{
public int MinLength { get; set; }
public int MaxLength { get; }
public StringLengthAttribute(int maxLength)
{
MaxLength = maxLength;
ErrorMessage = $"字符串长度不能超过 {maxLength} 个字符";
}
protected override bool ValidateValue(object value)
{
if (value == null) return !IsRequired;
string stringValue = value.ToString();
return stringValue.Length >= MinLength && stringValue.Length <= MaxLength;
}
}
// 使用示例
public class User
{
[StringLength(50, MinLength = 2, IsRequired = true, ErrorMessage = "用户名长度必须在2-50个字符之间")]
public string Username { get; set; }
[Range(18, 120, IsRequired = true, ErrorMessage = "年龄必须在18-120之间")]
public int Age { get; set; }
[StringLength(100, ErrorMessage = "邮箱长度不能超过100个字符")]
public string Email { get; set; }
}
public class AttributeDesignDemo
{
public static void DemonstrateAttributeDesign()
{
Console.WriteLine("\n=== 特性设计演示 ===");
var user = new User
{
Username = "A", // 太短
Age = 15, // 太小
Email = "test@example.com"
};
ValidateObject(user);
Console.WriteLine("\n修正后:");
user.Username = "张三";
user.Age = 25;
ValidateObject(user);
}
private static void ValidateObject(object obj)
{
Type type = obj.GetType();
bool isValid = true;
foreach (PropertyInfo property in type.GetProperties())
{
var validationAttributes = property.GetCustomAttributes<ValidationAttribute>();
foreach (var attribute in validationAttributes)
{
object value = property.GetValue(obj);
if (!attribute.IsValid(value))
{
Console.WriteLine($"{property.Name}: {attribute.ErrorMessage}");
isValid = false;
}
}
}
if (isValid)
{
Console.WriteLine("对象验证通过");
}
}
}
7. 实践练习
7.1 简单的ORM框架
// 数据库特性
[AttributeUsage(AttributeTargets.Class)]
public class TableAttribute : Attribute
{
public string Name { get; }
public TableAttribute(string name)
{
Name = name;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : Attribute
{
public string Name { get; set; }
public bool IsPrimaryKey { get; set; }
public bool IsAutoIncrement { get; set; }
public int MaxLength { get; set; }
public bool IsNullable { get; set; } = true;
public ColumnAttribute(string name = null)
{
Name = name;
}
}
// 实体类示例
[Table("Users")]
public class UserEntity
{
[Column("Id", IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; }
[Column("UserName", MaxLength = 50, IsNullable = false)]
public string Username { get; set; }
[Column("Email", MaxLength = 100)]
public string Email { get; set; }
[Column("CreatedAt", IsNullable = false)]
public DateTime CreatedAt { get; set; }
[Column("IsActive")]
public bool IsActive { get; set; }
}
// 简单的ORM实现
public class SimpleOrm
{
public static string GenerateCreateTableSql<T>()
{
Type type = typeof(T);
var tableAttribute = type.GetCustomAttribute<TableAttribute>();
if (tableAttribute == null)
{
throw new InvalidOperationException($"类 {type.Name} 没有 TableAttribute");
}
var sql = new StringBuilder();
sql.AppendLine($"CREATE TABLE {tableAttribute.Name} (");
var properties = type.GetProperties()
.Where(p => p.GetCustomAttribute<ColumnAttribute>() != null)
.ToList();
for (int i = 0; i < properties.Count; i++)
{
var property = properties[i];
var columnAttribute = property.GetCustomAttribute<ColumnAttribute>();
string columnName = columnAttribute.Name ?? property.Name;
string columnType = GetSqlType(property.PropertyType, columnAttribute);
sql.Append($" {columnName} {columnType}");
if (columnAttribute.IsPrimaryKey)
{
sql.Append(" PRIMARY KEY");
}
if (columnAttribute.IsAutoIncrement)
{
sql.Append(" IDENTITY(1,1)");
}
if (!columnAttribute.IsNullable)
{
sql.Append(" NOT NULL");
}
if (i < properties.Count - 1)
{
sql.AppendLine(",");
}
else
{
sql.AppendLine();
}
}
sql.AppendLine(");");
return sql.ToString();
}
public static string GenerateInsertSql<T>(T entity)
{
Type type = typeof(T);
var tableAttribute = type.GetCustomAttribute<TableAttribute>();
if (tableAttribute == null)
{
throw new InvalidOperationException($"类 {type.Name} 没有 TableAttribute");
}
var properties = type.GetProperties()
.Where(p => p.GetCustomAttribute<ColumnAttribute>() != null)
.Where(p => !p.GetCustomAttribute<ColumnAttribute>().IsAutoIncrement)
.ToList();
var columnNames = properties.Select(p =>
p.GetCustomAttribute<ColumnAttribute>().Name ?? p.Name);
var values = properties.Select(p => FormatValue(p.GetValue(entity)));
return $"INSERT INTO {tableAttribute.Name} ({string.Join(", ", columnNames)}) " +
$"VALUES ({string.Join(", ", values)})";
}
public static string GenerateSelectSql<T>()
{
Type type = typeof(T);
var tableAttribute = type.GetCustomAttribute<TableAttribute>();
if (tableAttribute == null)
{
throw new InvalidOperationException($"类 {type.Name} 没有 TableAttribute");
}
var properties = type.GetProperties()
.Where(p => p.GetCustomAttribute<ColumnAttribute>() != null);
var columnNames = properties.Select(p =>
p.GetCustomAttribute<ColumnAttribute>().Name ?? p.Name);
return $"SELECT {string.Join(", ", columnNames)} FROM {tableAttribute.Name}";
}
private static string GetSqlType(Type propertyType, ColumnAttribute columnAttribute)
{
// 处理可空类型
Type actualType = Nullable.GetUnderlyingType(propertyType) ?? propertyType;
return actualType.Name switch
{
nameof(Int32) => "INT",
nameof(Int64) => "BIGINT",
nameof(String) => columnAttribute.MaxLength > 0 ? $"NVARCHAR({columnAttribute.MaxLength})" : "NVARCHAR(MAX)",
nameof(DateTime) => "DATETIME2",
nameof(Boolean) => "BIT",
nameof(Decimal) => "DECIMAL(18,2)",
nameof(Double) => "FLOAT",
_ => "NVARCHAR(MAX)"
};
}
private static string FormatValue(object value)
{
if (value == null) return "NULL";
return value switch
{
string s => $"'{s.Replace("'", "''")}'",
DateTime dt => $"'{dt:yyyy-MM-dd HH:mm:ss}'",
bool b => b ? "1" : "0",
_ => value.ToString()
};
}
}
public class SimpleOrmDemo
{
public static void DemonstrateSimpleOrm()
{
Console.WriteLine("\n=== 简单ORM演示 ===");
// 生成建表SQL
string createTableSql = SimpleOrm.GenerateCreateTableSql<UserEntity>();
Console.WriteLine("建表SQL:");
Console.WriteLine(createTableSql);
// 生成查询SQL
string selectSql = SimpleOrm.GenerateSelectSql<UserEntity>();
Console.WriteLine("查询SQL:");
Console.WriteLine(selectSql);
// 生成插入SQL
var user = new UserEntity
{
Username = "张三",
Email = "zhangsan@example.com",
CreatedAt = DateTime.Now,
IsActive = true
};
string insertSql = SimpleOrm.GenerateInsertSql(user);
Console.WriteLine("\n插入SQL:");
Console.WriteLine(insertSql);
}
}
7.2 依赖注入容器
// 服务生命周期
public enum ServiceLifetime
{
Transient, // 每次请求都创建新实例
Singleton, // 单例
Scoped // 作用域内单例
}
// 服务描述符
public class ServiceDescriptor
{
public Type ServiceType { get; set; }
public Type ImplementationType { get; set; }
public ServiceLifetime Lifetime { get; set; }
public Func<IServiceProvider, object> Factory { get; set; }
public object Instance { get; set; }
}
// 简单的依赖注入容器
public interface IServiceProvider
{
T GetService<T>();
object GetService(Type serviceType);
}
public class SimpleContainer : IServiceProvider
{
private readonly Dictionary<Type, ServiceDescriptor> _services = new();
private readonly Dictionary<Type, object> _singletonInstances = new();
private readonly Dictionary<Type, object> _scopedInstances = new();
public void RegisterTransient<TInterface, TImplementation>()
where TImplementation : class, TInterface
{
_services[typeof(TInterface)] = new ServiceDescriptor
{
ServiceType = typeof(TInterface),
ImplementationType = typeof(TImplementation),
Lifetime = ServiceLifetime.Transient
};
}
public void RegisterSingleton<TInterface, TImplementation>()
where TImplementation : class, TInterface
{
_services[typeof(TInterface)] = new ServiceDescriptor
{
ServiceType = typeof(TInterface),
ImplementationType = typeof(TImplementation),
Lifetime = ServiceLifetime.Singleton
};
}
public void RegisterSingleton<TInterface>(TInterface instance)
{
_services[typeof(TInterface)] = new ServiceDescriptor
{
ServiceType = typeof(TInterface),
Lifetime = ServiceLifetime.Singleton,
Instance = instance
};
}
public void RegisterFactory<TInterface>(Func<IServiceProvider, TInterface> factory, ServiceLifetime lifetime = ServiceLifetime.Transient)
{
_services[typeof(TInterface)] = new ServiceDescriptor
{
ServiceType = typeof(TInterface),
Lifetime = lifetime,
Factory = provider => factory(provider)
};
}
public T GetService<T>()
{
return (T)GetService(typeof(T));
}
public object GetService(Type serviceType)
{
if (!_services.TryGetValue(serviceType, out ServiceDescriptor descriptor))
{
throw new InvalidOperationException($"服务 {serviceType.Name} 未注册");
}
return descriptor.Lifetime switch
{
ServiceLifetime.Singleton => GetSingleton(descriptor),
ServiceLifetime.Transient => CreateInstance(descriptor),
ServiceLifetime.Scoped => GetScoped(descriptor),
_ => throw new ArgumentException($"不支持的生命周期: {descriptor.Lifetime}")
};
}
private object GetSingleton(ServiceDescriptor descriptor)
{
if (_singletonInstances.TryGetValue(descriptor.ServiceType, out object instance))
{
return instance;
}
instance = CreateInstance(descriptor);
_singletonInstances[descriptor.ServiceType] = instance;
return instance;
}
private object GetScoped(ServiceDescriptor descriptor)
{
if (_scopedInstances.TryGetValue(descriptor.ServiceType, out object instance))
{
return instance;
}
instance = CreateInstance(descriptor);
_scopedInstances[descriptor.ServiceType] = instance;
return instance;
}
private object CreateInstance(ServiceDescriptor descriptor)
{
if (descriptor.Instance != null)
{
return descriptor.Instance;
}
if (descriptor.Factory != null)
{
return descriptor.Factory(this);
}
return CreateInstance(descriptor.ImplementationType);
}
private object CreateInstance(Type type)
{
// 获取构造函数
ConstructorInfo[] constructors = type.GetConstructors();
ConstructorInfo constructor = constructors
.OrderByDescending(c => c.GetParameters().Length)
.First();
// 解析构造函数参数
ParameterInfo[] parameters = constructor.GetParameters();
object[] args = new object[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
args[i] = GetService(parameters[i].ParameterType);
}
return Activator.CreateInstance(type, args);
}
public void ClearScope()
{
_scopedInstances.Clear();
}
}
// 示例服务
public interface ILogger
{
void Log(string message);
}
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine($"[LOG] {DateTime.Now:HH:mm:ss} - {message}");
}
}
public interface IRepository
{
void Save(string data);
}
public class DatabaseRepository : IRepository
{
private readonly ILogger _logger;
public DatabaseRepository(ILogger logger)
{
_logger = logger;
}
public void Save(string data)
{
_logger.Log($"保存数据到数据库: {data}");
}
}
public class UserService
{
private readonly IRepository _repository;
private readonly ILogger _logger;
public UserService(IRepository repository, ILogger logger)
{
_repository = repository;
_logger = logger;
}
public void CreateUser(string username)
{
_logger.Log($"创建用户: {username}");
_repository.Save($"用户数据: {username}");
}
}
public class DependencyInjectionDemo
{
public static void DemonstrateDependencyInjection()
{
Console.WriteLine("\n=== 依赖注入容器演示 ===");
var container = new SimpleContainer();
// 注册服务
container.RegisterSingleton<ILogger, ConsoleLogger>();
container.RegisterTransient<IRepository, DatabaseRepository>();
container.RegisterTransient<UserService, UserService>();
// 使用工厂注册
container.RegisterFactory<string>(provider => "配置字符串", ServiceLifetime.Singleton);
// 解析服务
var userService1 = container.GetService<UserService>();
var userService2 = container.GetService<UserService>();
Console.WriteLine($"UserService实例相同: {ReferenceEquals(userService1, userService2)}");
// 测试Logger单例
var logger1 = container.GetService<ILogger>();
var logger2 = container.GetService<ILogger>();
Console.WriteLine($"Logger实例相同: {ReferenceEquals(logger1, logger2)}");
// 使用服务
userService1.CreateUser("张三");
userService2.CreateUser("李四");
}
}
8. 章节总结
反射和特性是C#中强大的元编程工具,它们为开发者提供了在运行时检查和操作类型信息的能力。通过本章的学习,我们掌握了:
核心概念
- 反射基础:理解Type类、获取类型信息、成员信息检查
- 动态调用:运行时创建对象、调用方法、访问属性
- 特性系统:内置特性使用、自定义特性设计、特性读取和应用
- 性能优化:反射缓存策略、表达式树编译、委托优化
重要技能
- 类型检查和转换:安全的类型操作和转换
- 动态代码生成:使用表达式树和Emit生成高性能代码
- 元数据驱动编程:基于特性的配置和验证
- 框架设计:ORM、依赖注入、序列化等框架的实现原理
最佳实践
- 性能考虑:缓存反射信息、使用编译委托优化性能
- 安全性:验证类型安全、防止恶意代码执行
- 异常处理:正确处理反射相关异常
- 设计原则:特性的单一职责、可扩展性设计
实际应用
- 对象映射:自动化对象转换和数据传输
- 配置绑定:将配置数据绑定到强类型对象
- ORM框架:数据库映射和SQL生成
- 依赖注入:服务容器和依赖解析
反射和特性虽然功能强大,但也要注意性能开销和安全性问题。在实际开发中,应该根据具体需求选择合适的技术方案,在功能性和性能之间找到平衡点。
下一章我们将学习LINQ和表达式,探索C#中强大的查询和函数式编程特性。
1.2 成员信息获取
public class MemberInfoDemo
{
public static void DemonstrateMemberInfo()
{
Console.WriteLine("\n=== 成员信息获取演示 ===");
Type personType = typeof(Person);
Console.WriteLine("\n--- 构造函数信息 ---");
DemonstrateConstructors(personType);
Console.WriteLine("\n--- 属性信息 ---");
DemonstrateProperties(personType);
Console.WriteLine("\n--- 方法信息 ---");
DemonstrateMethods(personType);
Console.WriteLine("\n--- 字段信息 ---");
DemonstrateFields(typeof(Student));
Console.WriteLine("\n--- 事件信息 ---");
DemonstrateEvents(typeof(EventPublisher));
}
private static void DemonstrateConstructors(Type type)
{
ConstructorInfo[] constructors = type.GetConstructors();
Console.WriteLine($"构造函数数量: {constructors.Length}");
foreach (var constructor in constructors)
{
ParameterInfo[] parameters = constructor.GetParameters();
string parameterList = string.Join(", ", parameters.Select(p => $"{p.ParameterType.Name} {p.Name}"));
Console.WriteLine($" 构造函数: {type.Name}({parameterList})");
Console.WriteLine($" 是否为公共: {constructor.IsPublic}");
Console.WriteLine($" 是否为静态: {constructor.IsStatic}");
}
}
private static void DemonstrateProperties(Type type)
{
PropertyInfo[] properties = type.GetProperties();
Console.WriteLine($"属性数量: {properties.Length}");
foreach (var property in properties)
{
Console.WriteLine($" 属性: {property.PropertyType.Name} {property.Name}");
Console.WriteLine($" 可读: {property.CanRead}");
Console.WriteLine($" 可写: {property.CanWrite}");
if (property.CanRead)
{
MethodInfo getter = property.GetGetMethod();
Console.WriteLine($" Getter访问级别: {GetAccessLevel(getter)}");
}
if (property.CanWrite)
{
MethodInfo setter = property.GetSetMethod();
Console.WriteLine($" Setter访问级别: {GetAccessLevel(setter)}");
}
}
}
private static void DemonstrateMethods(Type type)
{
MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
Console.WriteLine($"声明的公共实例方法数量: {methods.Length}");
foreach (var method in methods)
{
if (method.IsSpecialName) continue; // 跳过属性访问器等特殊方法
ParameterInfo[] parameters = method.GetParameters();
string parameterList = string.Join(", ", parameters.Select(p => $"{p.ParameterType.Name} {p.Name}"));
Console.WriteLine($" 方法: {method.ReturnType.Name} {method.Name}({parameterList})");
Console.WriteLine($" 是否为虚方法: {method.IsVirtual}");
Console.WriteLine($" 是否为抽象方法: {method.IsAbstract}");
Console.WriteLine($" 是否为重写方法: {method.GetBaseDefinition() != method}");
}
}
private static void DemonstrateFields(Type type)
{
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
Console.WriteLine($"字段数量: {fields.Length}");
foreach (var field in fields)
{
Console.WriteLine($" 字段: {field.FieldType.Name} {field.Name}");
Console.WriteLine($" 是否为公共: {field.IsPublic}");
Console.WriteLine($" 是否为私有: {field.IsPrivate}");
Console.WriteLine($" 是否为静态: {field.IsStatic}");
Console.WriteLine($" 是否为只读: {field.IsInitOnly}");
Console.WriteLine($" 是否为常量: {field.IsLiteral}");
}
}
private static void DemonstrateEvents(Type type)
{
EventInfo[] events = type.GetEvents();
Console.WriteLine($"事件数量: {events.Length}");
foreach (var eventInfo in events)
{
Console.WriteLine($" 事件: {eventInfo.EventHandlerType?.Name} {eventInfo.Name}");
Console.WriteLine($" 添加方法: {eventInfo.GetAddMethod()?.Name}");
Console.WriteLine($" 移除方法: {eventInfo.GetRemoveMethod()?.Name}");
}
}
private static string GetAccessLevel(MethodInfo method)
{
if (method == null) return "无";
if (method.IsPublic) return "公共";
if (method.IsPrivate) return "私有";
if (method.IsFamily) return "受保护";
if (method.IsAssembly) return "内部";
if (method.IsFamilyOrAssembly) return "受保护内部";
return "未知";
}
}
// 示例类
public class Student
{
public string Name;
private int _age;
protected string _studentId;
internal static int _totalStudents;
public readonly DateTime _enrollmentDate;
public const string SCHOOL_NAME = "示例学校";
public int Age
{
get => _age;
set => _age = value;
}
public string StudentId
{
get => _studentId;
protected set => _studentId = value;
}
}
public class EventPublisher
{
public event Action<string> MessageReceived;
public event EventHandler<DataEventArgs> DataChanged;
public void PublishMessage(string message)
{
MessageReceived?.Invoke(message);
}
public void ChangeData(string data)
{
DataChanged?.Invoke(this, new DataEventArgs { Data = data });
}
}
public class DataEventArgs : EventArgs
{
public string Data { get; set; }
}
2. 动态调用和对象创建
2.1 动态创建对象实例
public class DynamicObjectCreation
{
public static void DemonstrateDynamicCreation()
{
Console.WriteLine("\n=== 动态对象创建演示 ===");
Console.WriteLine("\n--- 使用Activator.CreateInstance ---");
DemonstrateActivatorCreateInstance();
Console.WriteLine("\n--- 使用构造函数信息 ---");
DemonstrateConstructorInvocation();
Console.WriteLine("\n--- 泛型类型实例化 ---");
DemonstrateGenericInstantiation();
Console.WriteLine("\n--- 数组和集合创建 ---");
DemonstrateArrayAndCollectionCreation();
}
private static void DemonstrateActivatorCreateInstance()
{
// 无参构造函数
object person1 = Activator.CreateInstance(typeof(Person));
Console.WriteLine($"无参构造: {person1}");
// 有参构造函数
object person2 = Activator.CreateInstance(typeof(Person), "张三", 25);
Console.WriteLine($"有参构造: {person2}");
// 泛型方法
Person person3 = Activator.CreateInstance<Person>();
Console.WriteLine($"泛型方法: {person3}");
// 从字符串创建
Type stringType = Type.GetType("System.String");
object str = Activator.CreateInstance(stringType, "Hello World".ToCharArray());
Console.WriteLine($"字符串创建: {str}");
}
private static void DemonstrateConstructorInvocation()
{
Type personType = typeof(Person);
// 获取特定构造函数
ConstructorInfo constructor = personType.GetConstructor(new[] { typeof(string), typeof(int) });
if (constructor != null)
{
// 调用构造函数
object person = constructor.Invoke(new object[] { "李四", 30 });
Console.WriteLine($"构造函数调用: {person}");
}
// 获取所有构造函数并尝试调用
ConstructorInfo[] constructors = personType.GetConstructors();
foreach (var ctor in constructors)
{
ParameterInfo[] parameters = ctor.GetParameters();
if (parameters.Length == 0)
{
object instance = ctor.Invoke(null);
Console.WriteLine($"无参构造函数调用: {instance}");
}
else if (parameters.Length == 2 &&
parameters[0].ParameterType == typeof(string) &&
parameters[1].ParameterType == typeof(int))
{
object instance = ctor.Invoke(new object[] { "王五", 35 });
Console.WriteLine($"两参数构造函数调用: {instance}");
}
}
}
private static void DemonstrateGenericInstantiation()
{
// 创建List<string>
Type listType = typeof(List<>);
Type stringListType = listType.MakeGenericType(typeof(string));
object stringList = Activator.CreateInstance(stringListType);
Console.WriteLine($"创建的类型: {stringListType.Name}");
Console.WriteLine($"实例: {stringList}");
// 创建Dictionary<string, int>
Type dictType = typeof(Dictionary<,>);
Type stringIntDictType = dictType.MakeGenericType(typeof(string), typeof(int));
object stringIntDict = Activator.CreateInstance(stringIntDictType);
Console.WriteLine($"创建的字典类型: {stringIntDictType.Name}");
Console.WriteLine($"字典实例: {stringIntDict}");
}
private static void DemonstrateArrayAndCollectionCreation()
{
// 创建数组
Array intArray = Array.CreateInstance(typeof(int), 5);
Console.WriteLine($"创建的数组: {intArray.GetType().Name}, 长度: {intArray.Length}");
// 创建多维数组
Array multiArray = Array.CreateInstance(typeof(string), 3, 4);
Console.WriteLine($"多维数组: {multiArray.GetType().Name}, 维度: {multiArray.Rank}");
// 创建锯齿数组
Array jaggedArray = Array.CreateInstance(typeof(int[]), 3);
Console.WriteLine($"锯齿数组: {jaggedArray.GetType().Name}");
// 设置数组元素
for (int i = 0; i < intArray.Length; i++)
{
intArray.SetValue(i * 10, i);
}
Console.WriteLine($"数组内容: [{string.Join(", ", intArray.Cast<int>())}]");
}
}
2.2 动态方法调用
public class DynamicMethodInvocation
{
public static void DemonstrateDynamicInvocation()
{
Console.WriteLine("\n=== 动态方法调用演示 ===");
Console.WriteLine("\n--- 实例方法调用 ---");
DemonstrateInstanceMethodInvocation();
Console.WriteLine("\n--- 静态方法调用 ---");
DemonstrateStaticMethodInvocation();
Console.WriteLine("\n--- 泛型方法调用 ---");
DemonstrateGenericMethodInvocation();
Console.WriteLine("\n--- 属性访问 ---");
DemonstratePropertyAccess();
}
private static void DemonstrateInstanceMethodInvocation()
{
Person person = new Person("张三", 25);
Type personType = typeof(Person);
// 调用无参方法
MethodInfo sayHelloMethod = personType.GetMethod("SayHello");
sayHelloMethod?.Invoke(person, null);
// 调用有返回值的方法
MethodInfo getInfoMethod = personType.GetMethod("GetInfo");
object result = getInfoMethod?.Invoke(person, null);
Console.WriteLine($"GetInfo返回: {result}");
// 调用有参数的方法
MethodInfo compareToMethod = personType.GetMethod("CompareTo");
Person otherPerson = new Person("李四", 30);
object compareResult = compareToMethod?.Invoke(person, new object[] { otherPerson });
Console.WriteLine($"CompareTo返回: {compareResult}");
}
private static void DemonstrateStaticMethodInvocation()
{
// 调用静态方法
Type mathType = typeof(Math);
MethodInfo maxMethod = mathType.GetMethod("Max", new[] { typeof(int), typeof(int) });
object maxResult = maxMethod?.Invoke(null, new object[] { 10, 20 });
Console.WriteLine($"Math.Max(10, 20) = {maxResult}");
// 调用重载方法
MethodInfo maxDoubleMethod = mathType.GetMethod("Max", new[] { typeof(double), typeof(double) });
object maxDoubleResult = maxDoubleMethod?.Invoke(null, new object[] { 10.5, 20.3 });
Console.WriteLine($"Math.Max(10.5, 20.3) = {maxDoubleResult}");
// 调用DateTime的静态方法
Type dateTimeType = typeof(DateTime);
MethodInfo nowProperty = dateTimeType.GetProperty("Now")?.GetGetMethod();
object now = nowProperty?.Invoke(null, null);
Console.WriteLine($"DateTime.Now = {now}");
}
private static void DemonstrateGenericMethodInvocation()
{
// 创建一个包含泛型方法的类实例
var helper = new GenericHelper();
Type helperType = typeof(GenericHelper);
// 获取泛型方法定义
MethodInfo genericMethod = helperType.GetMethod("ProcessData");
if (genericMethod != null)
{
// 构造具体的泛型方法
MethodInfo stringMethod = genericMethod.MakeGenericMethod(typeof(string));
object stringResult = stringMethod.Invoke(helper, new object[] { "Hello" });
Console.WriteLine($"ProcessData<string>(\"Hello\") = {stringResult}");
MethodInfo intMethod = genericMethod.MakeGenericMethod(typeof(int));
object intResult = intMethod.Invoke(helper, new object[] { 42 });
Console.WriteLine($"ProcessData<int>(42) = {intResult}");
}
}
private static void DemonstratePropertyAccess()
{
Person person = new Person("张三", 25);
Type personType = typeof(Person);
// 获取属性值
PropertyInfo nameProperty = personType.GetProperty("Name");
object nameValue = nameProperty?.GetValue(person);
Console.WriteLine($"Name属性值: {nameValue}");
PropertyInfo ageProperty = personType.GetProperty("Age");
object ageValue = ageProperty?.GetValue(person);
Console.WriteLine($"Age属性值: {ageValue}");
// 设置属性值
nameProperty?.SetValue(person, "李四");
ageProperty?.SetValue(person, 30);
Console.WriteLine($"修改后的对象: {person}");
// 索引属性访问(如果有的话)
Type listType = typeof(List<string>);
var stringList = new List<string> { "A", "B", "C" };
PropertyInfo itemProperty = listType.GetProperty("Item");
if (itemProperty != null)
{
object firstItem = itemProperty.GetValue(stringList, new object[] { 0 });
Console.WriteLine($"List[0] = {firstItem}");
itemProperty.SetValue(stringList, "X", new object[] { 0 });
Console.WriteLine($"修改后 List[0] = {stringList[0]}");
}
}
}
// 辅助类
public class GenericHelper
{
public T ProcessData<T>(T data)
{
Console.WriteLine($"处理类型 {typeof(T).Name} 的数据: {data}");
return data;
}
public void GenericMethod<T1, T2>(T1 first, T2 second)
{
Console.WriteLine($"泛型方法: {first} ({typeof(T1).Name}), {second} ({typeof(T2).Name})");
}
}
3. 特性(Attributes)
3.1 内置特性的使用
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
public class BuiltInAttributesDemo
{
public static void DemonstrateBuiltInAttributes()
{
Console.WriteLine("\n=== 内置特性演示 ===");
Console.WriteLine("\n--- Obsolete特性 ---");
DemonstrateObsoleteAttribute();
Console.WriteLine("\n--- 序列化特性 ---");
DemonstrateSerializationAttributes();
Console.WriteLine("\n--- 条件编译特性 ---");
DemonstrateConditionalAttribute();
}
private static void DemonstrateObsoleteAttribute()
{
var demo = new ObsoleteDemo();
// 调用过时的方法(会产生编译警告)
demo.OldMethod();
// 调用新方法
demo.NewMethod();
// 尝试调用已移除的方法(会产生编译错误,这里注释掉)
// demo.RemovedMethod();
}
private static void DemonstrateSerializationAttributes()
{
var product = new Product
{
Id = 1,
Name = "示例产品",
Price = 99.99m,
InternalCode = "INTERNAL_001",
CreatedDate = DateTime.Now
};
Console.WriteLine($"产品对象: {product}");
// 这里可以演示序列化,但需要相应的序列化库
Console.WriteLine("序列化时,InternalCode字段将被忽略");
Console.WriteLine("Price属性将使用自定义名称'cost'");
}
private static void DemonstrateConditionalAttribute()
{
var logger = new ConditionalLogger();
logger.DebugLog("这是调试信息");
logger.ReleaseLog("这是发布信息");
Console.WriteLine("条件编译方法只在特定条件下执行");
}
}
// 演示Obsolete特性
public class ObsoleteDemo
{
[Obsolete("此方法已过时,请使用NewMethod代替")]
public void OldMethod()
{
Console.WriteLine("执行旧方法");
}
public void NewMethod()
{
Console.WriteLine("执行新方法");
}
[Obsolete("此方法已被移除", true)]
public void RemovedMethod()
{
Console.WriteLine("此方法不应被调用");
}
}
// 演示序列化特性
[DataContract]
public class Product
{
[DataMember]
public int Id { get; set; }
[DataMember]
[JsonPropertyName("product_name")]
public string Name { get; set; }
[DataMember(Name = "cost")]
public decimal Price { get; set; }
[JsonIgnore]
[IgnoreDataMember]
public string InternalCode { get; set; }
[DataMember]
public DateTime CreatedDate { get; set; }
public override string ToString()
{
return $"Product(Id={Id}, Name={Name}, Price={Price}, InternalCode={InternalCode})";
}
}
// 演示条件编译特性
public class ConditionalLogger
{
[System.Diagnostics.Conditional("DEBUG")]
public void DebugLog(string message)
{
Console.WriteLine($"[DEBUG] {message}");
}
[System.Diagnostics.Conditional("RELEASE")]
public void ReleaseLog(string message)
{
Console.WriteLine($"[RELEASE] {message}");
}
}
3.2 自定义特性
// 自定义特性定义
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property,
AllowMultiple = true, Inherited = true)]
public class DocumentationAttribute : Attribute
{
public string Description { get; }
public string Author { get; set; }
public string Version { get; set; }
public DateTime CreatedDate { get; set; }
public string[] Tags { get; set; }
public DocumentationAttribute(string description)
{
Description = description;
CreatedDate = DateTime.Now;
}
}
[AttributeUsage(AttributeTargets.Method)]
public class BenchmarkAttribute : Attribute
{
public int Iterations { get; set; } = 1;
public bool LogResults { get; set; } = true;
public string Category { get; set; } = "General";
}
[AttributeUsage(AttributeTargets.Property)]
public class ValidationAttribute : Attribute
{
public bool Required { get; set; }
public int MinLength { get; set; }
public int MaxLength { get; set; } = int.MaxValue;
public string Pattern { get; set; }
public string ErrorMessage { get; set; }
}
[AttributeUsage(AttributeTargets.Class)]
public class TableAttribute : Attribute
{
public string Name { get; }
public string Schema { get; set; } = "dbo";
public TableAttribute(string name)
{
Name = name;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : Attribute
{
public string Name { get; set; }
public bool IsPrimaryKey { get; set; }
public bool IsIdentity { get; set; }
public bool AllowNull { get; set; } = true;
public int MaxLength { get; set; }
public string DataType { get; set; }
}
// 使用自定义特性的示例类
[Documentation("用户实体类", Author = "开发团队", Version = "1.0",
Tags = new[] { "Entity", "User", "Database" })]
[Table("Users", Schema = "Identity")]
public class User
{
[Documentation("用户唯一标识符")]
[Column(Name = "user_id", IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
[Documentation("用户名", Author = "张三")]
[Validation(Required = true, MinLength = 3, MaxLength = 50,
ErrorMessage = "用户名长度必须在3-50个字符之间")]
[Column(Name = "username", MaxLength = 50, AllowNull = false)]
public string Username { get; set; }
[Documentation("用户邮箱地址")]
[Validation(Required = true, Pattern = @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$",
ErrorMessage = "请输入有效的邮箱地址")]
[Column(Name = "email", MaxLength = 100, AllowNull = false)]
public string Email { get; set; }
[Documentation("用户年龄")]
[Validation(ErrorMessage = "年龄必须在0-150之间")]
[Column(Name = "age", AllowNull = true)]
public int? Age { get; set; }
[Documentation("账户创建时间")]
[Column(Name = "created_at", DataType = "datetime2", AllowNull = false)]
public DateTime CreatedAt { get; set; }
[Benchmark(Iterations = 1000, Category = "UserOperations")]
public string GetDisplayName()
{
return $"{Username} ({Email})";
}
[Documentation("验证用户数据")]
[Benchmark(Iterations = 100, LogResults = false)]
public bool ValidateData()
{
return !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Email);
}
}
public class CustomAttributeDemo
{
public static void DemonstrateCustomAttributes()
{
Console.WriteLine("\n=== 自定义特性演示 ===");
Console.WriteLine("\n--- 读取类级别特性 ---");
DemonstrateClassAttributes();
Console.WriteLine("\n--- 读取属性特性 ---");
DemonstratePropertyAttributes();
Console.WriteLine("\n--- 读取方法特性 ---");
DemonstrateMethodAttributes();
Console.WriteLine("\n--- 特性驱动的验证 ---");
DemonstrateAttributeBasedValidation();
}
private static void DemonstrateClassAttributes()
{
Type userType = typeof(User);
// 获取Documentation特性
var docAttributes = userType.GetCustomAttributes<DocumentationAttribute>();
foreach (var doc in docAttributes)
{
Console.WriteLine($"类文档: {doc.Description}");
Console.WriteLine($" 作者: {doc.Author}");
Console.WriteLine($" 版本: {doc.Version}");
Console.WriteLine($" 标签: {string.Join(", ", doc.Tags ?? new string[0])}");
}
// 获取Table特性
var tableAttribute = userType.GetCustomAttribute<TableAttribute>();
if (tableAttribute != null)
{
Console.WriteLine($"数据库表: {tableAttribute.Schema}.{tableAttribute.Name}");
}
}
private static void DemonstratePropertyAttributes()
{
Type userType = typeof(User);
PropertyInfo[] properties = userType.GetProperties();
foreach (var property in properties)
{
Console.WriteLine($"\n属性: {property.Name}");
// Documentation特性
var docAttribute = property.GetCustomAttribute<DocumentationAttribute>();
if (docAttribute != null)
{
Console.WriteLine($" 文档: {docAttribute.Description}");
if (!string.IsNullOrEmpty(docAttribute.Author))
Console.WriteLine($" 作者: {docAttribute.Author}");
}
// Validation特性
var validationAttribute = property.GetCustomAttribute<ValidationAttribute>();
if (validationAttribute != null)
{
Console.WriteLine($" 验证规则:");
Console.WriteLine($" 必填: {validationAttribute.Required}");
if (validationAttribute.MinLength > 0)
Console.WriteLine($" 最小长度: {validationAttribute.MinLength}");
if (validationAttribute.MaxLength < int.MaxValue)
Console.WriteLine($" 最大长度: {validationAttribute.MaxLength}");
if (!string.IsNullOrEmpty(validationAttribute.Pattern))
Console.WriteLine($" 模式: {validationAttribute.Pattern}");
if (!string.IsNullOrEmpty(validationAttribute.ErrorMessage))
Console.WriteLine($" 错误消息: {validationAttribute.ErrorMessage}");
}
// Column特性
var columnAttribute = property.GetCustomAttribute<ColumnAttribute>();
if (columnAttribute != null)
{
Console.WriteLine($" 数据库列:");
Console.WriteLine($" 列名: {columnAttribute.Name ?? property.Name}");
Console.WriteLine($" 主键: {columnAttribute.IsPrimaryKey}");
Console.WriteLine($" 自增: {columnAttribute.IsIdentity}");
Console.WriteLine($" 允许空值: {columnAttribute.AllowNull}");
if (columnAttribute.MaxLength > 0)
Console.WriteLine($" 最大长度: {columnAttribute.MaxLength}");
if (!string.IsNullOrEmpty(columnAttribute.DataType))
Console.WriteLine($" 数据类型: {columnAttribute.DataType}");
}
}
}
private static void DemonstrateMethodAttributes()
{
Type userType = typeof(User);
MethodInfo[] methods = userType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
foreach (var method in methods)
{
if (method.IsSpecialName) continue; // 跳过属性访问器
Console.WriteLine($"\n方法: {method.Name}");
// Documentation特性
var docAttribute = method.GetCustomAttribute<DocumentationAttribute>();
if (docAttribute != null)
{
Console.WriteLine($" 文档: {docAttribute.Description}");
}
// Benchmark特性
var benchmarkAttribute = method.GetCustomAttribute<BenchmarkAttribute>();
if (benchmarkAttribute != null)
{
Console.WriteLine($" 基准测试:");
Console.WriteLine($" 迭代次数: {benchmarkAttribute.Iterations}");
Console.WriteLine($" 记录结果: {benchmarkAttribute.LogResults}");
Console.WriteLine($" 分类: {benchmarkAttribute.Category}");
}
}
}
private static void DemonstrateAttributeBasedValidation()
{
var user = new User
{
Id = 1,
Username = "ab", // 太短
Email = "invalid-email", // 无效格式
Age = 25,
CreatedAt = DateTime.Now
};
Console.WriteLine("\n验证用户对象:");
bool isValid = ValidateObject(user);
Console.WriteLine($"验证结果: {(isValid ? "通过" : "失败")}");
}
private static bool ValidateObject(object obj)
{
Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties();
bool isValid = true;
foreach (var property in properties)
{
var validationAttribute = property.GetCustomAttribute<ValidationAttribute>();
if (validationAttribute == null) continue;
object value = property.GetValue(obj);
string stringValue = value?.ToString() ?? "";
// 必填验证
if (validationAttribute.Required && string.IsNullOrEmpty(stringValue))
{
Console.WriteLine($" {property.Name}: {validationAttribute.ErrorMessage ?? "此字段为必填项"}");
isValid = false;
continue;
}
if (!string.IsNullOrEmpty(stringValue))
{
// 长度验证
if (stringValue.Length < validationAttribute.MinLength)
{
Console.WriteLine($" {property.Name}: 长度不能少于{validationAttribute.MinLength}个字符");
isValid = false;
}
if (stringValue.Length > validationAttribute.MaxLength)
{
Console.WriteLine($" {property.Name}: 长度不能超过{validationAttribute.MaxLength}个字符");
isValid = false;
}
// 模式验证
if (!string.IsNullOrEmpty(validationAttribute.Pattern))
{
if (!System.Text.RegularExpressions.Regex.IsMatch(stringValue, validationAttribute.Pattern))
{
Console.WriteLine($" {property.Name}: {validationAttribute.ErrorMessage ?? "格式不正确"}");
isValid = false;
}
}
}
}
return isValid;
}
}