首頁 >後端開發 >C++ >如何在C#中動態為屬性新增驗證屬性?

如何在C#中動態為屬性新增驗證屬性?

Patricia Arquette
Patricia Arquette原創
2025-01-03 09:40:40483瀏覽

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