Is it possible to add an attribute to a property in a partial class?

前端 未结 4 492
隐瞒了意图╮
隐瞒了意图╮ 2020-12-07 00:53

I don\'t think it\'s possible but since I haven\'t got a definite clarity from MSDN, I feel that it\'s best to ask. Suppose that we have a class as follows.

         


        
相关标签:
4条回答
  • 2020-12-07 01:34

    The best we could to to ensure decimals serialized to 2 decimal places was tp:

    1. Use XlmAttributeOverides to ignore the decimal filed i.e not serialze it

    var xmlAttributeOverrides = new XmlAttributeOverrides(); var ctrlSumAttributes = new XmlAttributes { XmlIgnore = true }; xmlAttributeOverrides.Add(typeof(Sepa.GroupHeader39), "CtrlSum", ctrlSumAttributes); var ser = new XmlSerializer( typeof( Sepa.Document ), xmlAttributeOverrides);

    1. Use a partial class to add a string serialization of the ignored field

    public partial class GroupHeader39 { [XmlElement("CtrlSum")] public string CtrlSumString { get => CtrlSum.ToString("F2"); set { /* required to work */ } } }

    I hope this helps someone out with this issue.

    0 讨论(0)
  • 2020-12-07 01:37

    No, you can't.

    You can only attach attributes to members you declare there and then, and unless the member is also declared as partial (so that you may reimplement it elsewhere) you cannot attach attributes to members declared in another partial file.

    0 讨论(0)
  • 2020-12-07 01:51

    Based on your requirements, as an option you can consider using:

    • MetadataType attribute

    Note: The attributes that you can register this way are not really your class attributes, but most frameworks like ASP.NET MVC use them like your class native attributes.

    If you want to add data annotations attributes, specially in as ASP.NET MVC project, you will find this way helpful.

    Also for other frameworks like Windows Forms that don't support MetadataTypeAttribute you can simply add support using AssociatedMetadataTypeTypeDescriptionProvider.

    The solution is not restricted to data annotations attributes and you can use all kind of attributes that are meaningful for your libraries and frameworks.

    How to define additional attributes?

    You can create a metadata class that contains properties of your original class decorated by suitable attributes and then decorate the partial class by MetadataType attribute and introduce the metadata class for your original class.

    How to see the impact of those attributes?

    Frameworks like ASP.NET MVC use those attributes like they are defined in your original class.

    Also You can register AssociatedMetadataTypeTypeDescriptionProvider as provider for your original type for other frameworks or components that may want to use TypeDescriptor to get information about your type.

    Are they really my class attributes?

    Please pay attention, this way, the attributes really don't belong to your original class, but for most frameworks, like ASP.NET MVC or Windows Forms that use TypeDescriptor to get information about types, they act like your class original attributes.

    So if you want to get attributes for a property using reflection, you can't see them, but if you you use TypeDescriptor mechanism, you can see them.

    An Example

    Hazaa Class:

    public partial class Hazaa
    {
        public int Shazoo { get; set; }
    }
    

    HazaaMetadata Class

    [MetadataType(typeof(HazaaMetadata))]
    public partial class Hazaa
    {
    }
    
    public class HazaaMetadata
    {
        [DisplayName("Shazoo Name")]
        public int Shazoo { get; set; }
    }
    

    ASP.NET MVC Usage

    you don't need to do anything else to make that DisplayName work, you can simply use Html.Labelfor or Html.DisplayNameFor to see the impact. It will show "Shazoo Name" as label text.

    Windows Forms Usage

    Some where in your application (like form load, main, ...) register the provider this way:

    var provider = new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Hazaa));
    TypeDescriptor.AddProvider(provider, typeof(Hazaa));
    

    And as a result, you will see PropertyGrid and DataGridView use "Shazoo Name" as caption for property and column title.

    0 讨论(0)
  • 2020-12-07 01:52

    of course you can do it using Metadata as follow:

    public partial class Hazaa : EntityBase
    {
        public int Shazoo { get; set; }
    }
    
    [MetadataTypeAttribute(typeof(HazaaMetadata))]
    public partial class Hazaa : EntityBase
    {
        internal sealed class HazaaMetadata
        {
            [SuperCool]
            public int Shazoo { get; set; }
        }
    }
    
    0 讨论(0)
提交回复
热议问题