首页 >后端开发 >C++ >如何在C#中动态为属性添加验证属性?

如何在C#中动态为属性添加验证属性?

Patricia Arquette
Patricia Arquette原创
2025-01-03 09:40:40456浏览

How Can I Dynamically Add Validation Attributes to Properties in C#?

动态向属性添加属性

此代码示例演示如何在运行时向属性添加验证属性。它利用反射来访问属性的 FillAttributes 方法并注入所需的属性。

代码分析

// Get PropertyDescriptor object for the given property name
var propDesc = TypeDescriptor.GetProperties(typeof(T))[propName];

// Get FillAttributes methodinfo delegate
var methodInfo = propDesc.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public |
                                                      BindingFlags.NonPublic)
    .FirstOrDefault(m => m.IsFamily || m.IsPublic && m.Name == "FillAttributes");

// Create Validation attribute
var attribute = new RequiredAttribute();
var attributes = new ValidationAttribute[] { attribute };

// Invoke FillAttribute method
methodInfo.Invoke(propDesc, new object[] { attributes });

异常分析

但是,在执行时,您可能会遇到“集合具有固定大小”例外。发生这种情况是因为属性的验证属性集合被定义为固定大小的数组。为了解决这个问题,我们需要用一个更大的新数组替换现有的数组。

解决方案

要解决此问题,您可以实现自定义属性缓存系统来动态存储和应用属性。示例实现可以是:

// Initialize cache dictionary and synchronization mechanism
private static readonly Dictionary<Type, Attribute[]> AttributeCache = new Dictionary<Type, Attribute[]>();
private static readonly object SyncObject = new object();

protected override Attribute[] GetCustomAttributes(Type attributeType, bool inherit)
{
    if (AttributeCache.TryGetValue(this.GetType(), out Attribute[] cachedAttrs))
    {
        return cachedAttrs;
    }
    else
    {
        lock (SyncObject)
        {
            if (!AttributeCache.TryGetValue(this.GetType(), out cachedAttrs))
            {
                cachedAttrs = base.GetCustomAttributes(attributeType, inherit);
                AttributeCache.Add(this.GetType(), cachedAttrs);
            }
        }
        return cachedAttrs;
    }
}

使用此自定义缓存机制,代码将在运行时成功向属性添加验证属性,而不会导致固定大小集合异常。

以上是如何在C#中动态为属性添加验证属性?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn