2011-12-05 16 views
25

पर एक कस्टम विशेषता की अनुमति दें क्या संकलक को केवल विशिष्ट संपत्ति प्रकारों जैसे int, short, string (सभी आदिम प्रकार) पर उपयोग करने के लिए कस्टम विशेषता के उपयोग को प्रतिबंधित करने का कोई तरीका है?
AttributeUsageAttribute के वैलीडॉन- AttributeTargets गणना के समान।केवल विशिष्ट प्रकार

+0

नहीं, यह संभव नहीं है। आप जितना अधिक कर सकते हैं वह एक यूनिट टेस्ट लिखता है जो प्रतिबिंब का उपयोग करता है और इसके उपयोग को मान्य करता है। लेकिन संकलक में कुछ भी ऐसा नहीं करेगा। – Amy

+0

भी; आप अपने नियंत्रण के बाहर कक्षाओं में विशेषताओं को जोड़ नहीं सकते * वैसे भी * - ताकि आप 'int' या' string' में विशेषताओं को जोड़ नहीं सकें। क्या आपका मतलब है "केवल उन गुणों के लिए जो * * int 'या' string' 'हैं? यदि हां, तो जवाब अभी भी "नहीं" है; पी –

+0

@MarcGravell का मैं int int, स्ट्रिंग गुणों का उल्लेख करता हूं और int वर्ग को स्वयं नहीं बदलता, लेकिन मैं संपादित करूंगा। जवाब के लिए धन्यवाद। – gdoron

उत्तर

21

नहीं, आप मूल रूप से नहीं कर सकते हैं। आप इसे struct बनाम class बनाम interface पर सीमित कर सकते हैं, जो इसके बारे में है। इसके अलावा: आप वैसे भी अपने कोड के बाहर के प्रकारों में विशेषताओं को जोड़ नहीं सकते हैं (TypeDescriptor के माध्यम से छोड़कर, जो समान नहीं है)।

4

आप अपनी विशेषता वर्ग के सही उपयोग को लागू करने के लिए स्वयं कोड लिख सकते हैं, लेकिन जितना आप कर सकते हैं उतना ही कर सकते हैं।

+5

साइड नोट: किसी विशेषता के पास इसके स्वयं के संदर्भ तक कोई पहुंच नहीं है, इसलिए यहां कोई भी चेक प्रतिबिंब कोड में होना चाहिए जो विशेषता –

+1

के लिए पूछताछ करता है मैंने एक बार यूनिट टेस्ट (एनयूनीट) लिखा था मेरे "स्वीकार्य" गुण उपयोग को सत्यापित करने के लिए सेसिल। – Amy

+0

अच्छा समय ..... –

4

आप इसे जांचने के लिए इस यूनिट परीक्षण को चला सकते हैं।

सबसे पहले, की घोषणा सत्यापन PropertyType विशेषता:

[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 
} 
संबंधित मुद्दे