有沒有辦法強制編譯器限制自定義屬性的使用僅用於特定的屬性類型如int,short,string(所有基本類型)?
類似於AttributeUsageAttribute的ValidOn-AttributeTargets枚舉。只允許在特定類型的自定義屬性
回答
不,你基本上不能。您可以將其限制爲struct
vs class
vs interface
,就是這樣。 Plus:無論如何你都不能將屬性添加到你的代碼之外的類型(除了通過TypeDescriptor
,這是不一樣的)。
您可以自己編寫代碼來強制正確使用您的屬性類,但這與您所能做的一樣多。
備註:一個屬性無法訪問它自己的上下文,因此這裏的任何檢查都必須位於查詢屬性 –
的反射代碼中。一旦使用過,我寫了一個單元測試(NUnit)塞西爾來驗證我的「允許」屬性用法。 – Amy
美好時光..... –
你可以運行這個單元測試來檢查它。
首先,聲明驗證屬性屬性類型:
[AttributeUsage(AttributeTargets.Class)]
// [JetBrains.Annotations.BaseTypeRequired(typeof(Attribute))] uncomment if you use JetBrains.Annotations
public class PropertyTypeAttribute : Attribute
{
public Type[] Types { get; private set; }
public PropertyTypeAttribute(params Type[] types)
{
Types = types;
}
}
創建單元測試:
[TestClass]
public class TestPropertyType
{
public static Type GetNullableUnderlying(Type nullableType)
{
return Nullable.GetUnderlyingType(nullableType) ?? nullableType;
}
[TestMethod]
public void Test_PropertyType()
{
var allTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes());
var allPropertyInfos = allTypes.SelectMany(a => a.GetProperties()).ToArray();
foreach (var propertyInfo in allPropertyInfos)
{
var propertyType = GetNullableUnderlying(propertyInfo.PropertyType);
foreach (var attribute in propertyInfo.GetCustomAttributes(true))
{
var attributes = attribute.GetType().GetCustomAttributes(true).OfType<PropertyTypeAttribute>();
foreach (var propertyTypeAttr in attributes)
if (!propertyTypeAttr.Types.Contains(propertyType))
throw new Exception(string.Format(
"Property '{0}.{1}' has invalid type: '{2}'. Allowed types for attribute '{3}': {4}",
propertyInfo.DeclaringType,
propertyInfo.Name,
propertyInfo.PropertyType,
attribute.GetType(),
string.Join(",", propertyTypeAttr.Types.Select(x => "'" + x.ToString() + "'"))));
}
}
}
}
你的屬性,例如只允許小數屬性類型:
[AttributeUsage(AttributeTargets.Property)]
[PropertyType(typeof(decimal))]
public class PriceAttribute : Attribute
{
}
實施例模型:
public class TestModel
{
[Price]
public decimal Price1 { get; set; } // ok
[Price]
public double Price2 { get; set; } // error
}
- 1. C#屬性用法:只允許特定數據類型屬性的屬性
- 2. 只允許ArrayList中的特定類型
- 3. 不允許自定義屬性
- 4. 只允許某些類型的屬性
- 5. 只允許設置特定類/實例的屬性
- 6. ActiveRecord是否允許自定義類型?
- 7. 從自定義類獲取特定類型的屬性
- 8. 如何允許只讀綁定到自定義控件DependencyProperty的內部屬性?
- 9. 只允許來自特定域
- 10. 允許在TinyMCE的自定義HTML屬性在EPiServer
- 11. 允許更新特定集合屬性
- 12. Rails的用戶PARAMS只允許某些特定屬性
- 13. Swift類自定義類型屬性
- 14. 陣列類型的自定義屬性
- 15. 自定義類型的Android屬性?
- 16. php:自定義類型的屬性
- 17. 只讀自定義屬性
- 18. xPages自定義控件與允許多個實例的自定義屬性組
- 19. 自定義Android視圖的自定義類型屬性
- 20. 自定義產品類型的自定義屬性
- 21. 只允許特定的值只有
- 22. 只允許在特定的語言
- 23. Cancan允許更新模型的特定屬性
- 24. 雄辯的ORM:定義允許的模型屬性
- 25. 自定義組件屬性類型
- 26. SqlTableProfileProvider和自定義類型屬性
- 27. OpenLdap添加自定義屬性類型
- 28. 自定義屬性和類型檢查
- 29. 1C Bitrix:屬性自定義類型
- 30. MongoMapper和自定義類型屬性
不,這是不可能的。你能做的最多的是編寫一個使用反射並驗證其用法的單元測試。但編譯器不會做這件事。 – Amy
也;你不能將屬性添加到你的控制之外的類*無論如何* - 所以你不能添加屬性到'int'或'string'。你的意思是「只對屬於*'int'或'string'的屬性嗎?如果答案是肯定的,答案仍然是「否」; p –
@MarcGravell ofcourse I ment int,字符串屬性和不改變int類本身,但我會編輯。感謝你的回答。 – gdoron