2011-12-05 90 views
25

有沒有辦法強制編譯器限制自定義屬性的使用僅用於特定的屬性類型如int,short,string(所有基本類型)?
類似於AttributeUsageAttribute的ValidOn-AttributeTargets枚舉。只允許在特定類型的自定義屬性

+0

不,這是不可能的。你能做的最多的是編寫一個使用反射並驗證其用法的單元測試。但編譯器不會做這件事。 – Amy

+0

也;你不能將屬性添加到你的控制之外的類*無論如何* - 所以你不能添加屬性到'int'或'string'。你的意思是「只對屬於*'int'或'string'的屬性嗎?如果答案是肯定的,答案仍然是「否」; p –

+0

@MarcGravell ofcourse I ment int,字符串屬性和不改變int類本身,但我會編輯。感謝你的回答。 – gdoron

回答

21

不,你基本上不能。您可以將其限制爲struct vs class vs interface,就是這樣。 Plus:無論如何你都不能將屬性添加到你的代碼之外的類型(除了通過TypeDescriptor,這是不一樣的)。

4

您可以自己編寫代碼來強制正確使用您的屬性類,但這與您所能做的一樣多。

+5

備註:一個屬性無法訪問它自己的上下文,因此這裏的任何檢查都必須位於查詢屬性 –

+1

的反射代碼中。一旦使用過,我寫了一個單元測試(NUnit)塞西爾來驗證我的「允許」屬性用法。 – Amy

+0

美好時光..... –

4

你可以運行這個單元測試來檢查它。

首先,聲明驗證屬性屬性類型:

[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 
}