首页 文章

最有用的属性[关闭]

提问于
浏览
749

我知道属性非常有用 . 有一些预定义的,例如 [Browsable(false)] ,它允许您在属性选项卡中隐藏属性 . 这是一个解释属性的好问题:What are attributes in .NET?

What are the predefined attributes (and their namespace) you actually use in your projects?

30 回答

  • 43

    在我的脑海中,这是一个快速列表,大致按使用频率排序,我在一个大项目中实际使用的预定义属性(~500k LoCs):

    Flags,Serializable,WebMethod,COMVisible,TypeConverter,Conditional,ThreadStatic,Obsolete,InternalsVisibleTo,DebuggerStepThrough .

  • 6

    [DeploymentItem("myFile1.txt")] MSDN Doc on DeploymentItem

    如果您正在测试文件或使用该文件作为测试的输入,这非常有用 .

  • 8

    在调试期间将鼠标悬停在Type的实例上时, [DebuggerDisplay] 对于快速查看Type的自定义输出非常有用 . 例:

    [DebuggerDisplay("FirstName={FirstName}, LastName={LastName}")]
    class Customer
    {
        public string FirstName;
        public string LastName;
    }
    

    这是它应该在调试器中查看的方式:

    alt text http://serialize.wordpress.com/files/2008/10/temp.jpg

    另外,值得一提的是 [WebMethod] 属性设置 CacheDuration 可以避免不必要的Web服务方法的执行 .

  • 6

    在我看来,System.Obsolete是框架中最有用的属性之一 . 对不应再使用的代码发出警告的能力非常有用 . 我喜欢有办法告诉开发人员应该不再使用某些东西,以及有办法解释原因并指出更好/新的做事方式 .

    Conditional attribute对于调试使用也非常方便 . 它允许您在代码中添加方法以用于调试目的,这些方法在构建解决方案时不会被编译 .

    然后有很多特定于Web控件的属性我觉得很有用,但是那些更具体,并且在我发现的服务器控件开发之外没有任何用途 .

  • 22

    [Flags]非常方便 . 句法糖肯定,但仍然相当不错 .

    [Flags] 
    enum SandwichStuff
    {
       Cheese = 1,
       Pickles = 2,
       Chips = 4,
       Ham = 8,
       Eggs = 16,
       PeanutButter = 32,
       Jam = 64
    };
    
    public Sandwich MakeSandwich(SandwichStuff stuff)
    {
       Console.WriteLine(stuff.ToString());
       // ...
    }
    
    // ...
    
    MakeSandwich(SandwichStuff.Cheese 
       | SandwichStuff.Ham 
       | SandwichStuff.PeanutButter);
    // produces console output: "Cheese, Ham, PeanutButter"
    

    Leppie 指出了一些我没有意识到的东西,这反而削弱了我对这个属性的热情:它确实指示编译器允许位组合作为枚举变量的有效值,编译器允许这个用于枚举 . 我的C背景显示......叹息

  • 6

    我喜欢[DebuggerStepThrough] from System.Diagnostics .

    避免单步执行那些单线无操作方法或属性非常方便(如果你被迫在没有自动属性的早期.Net中工作) . 将属性放在一个简短的方法或属性的getter或setter上,即使在调试器中点击“step into”,你也会飞得很快 .

  • 67

    为了它's worth, here' s a list of all .NET attributes . 有几百个 .

    我不知道其他人,但我有一些严肃的RTFM要做!

  • 192

    我的投票将是 [Conditional]

    [Conditional("DEBUG")]
    public void DebugOnlyFunction()
    {
        // your code here
    }
    

    您可以使用它来添加具有高级调试功能的功能;与 Debug.Write 类似,它仅在调试版本中调用,因此允许您将复杂的调试逻辑封装在程序的主流程之外 .

  • 14

    我总是使用 DisplayNameDescriptionDefaultValue 属性来覆盖我的用户控件,自定义控件或我将通过属性网格编辑的任何类的公共属性 . .NET PropertyGrid使用这些标记来格式化未设置为默认值的名称,描述面板和粗体值 .

    [DisplayName("Error color")]
    [Description("The color used on nodes containing errors.")]
    [DefaultValue(Color.Red)]
    public Color ErrorColor
    {
        ...
    }
    

    我只是希望Visual Studio的IntelliSense在没有找到XML注释的情况下考虑 Description 属性 . 这样可以避免两次重复相同的句子 .

  • 55

    [Serializable] 始终用于将对象序列化和反序列化到外部数据源(如xml)或从远程服务器反序列化 . More about it here.

  • 258

    在Hofstadtian精神中, [Attribute] 属性非常有用,因为它使用属性而不是接口来实现插件系统,向枚举添加描述,模拟多个调度和其他技巧 .

  • 131

    Here是关于有趣属性InternalsVisibleTo的帖子 . 基本上它是什么模仿C朋友访问功能 . 它非常方便单元测试 .

  • 43

    我发现[DefaultValue]非常有用 .

  • 648

    我建议 [TestFixture][Test] 来自nUnit库 .

    代码中的单元测试为重构和编码文档提供了安全性 .

  • 27
    [XmlIgnore]
    

    因为这允许你忽略(在任何xml序列化中)'父'对象,否则在保存时会导致异常 .

  • 173

    它没有良好的名称,在框架中没有得到很好的支持,并且不需要参数,但是这个属性对于不可变类是一个有用的标记:

    [ImmutableObject(true)]
    
  • 8

    我喜欢将 [ThreadStatic] 属性与基于线程和堆栈的编程结合使用 . 例如,如果我想要一个我希望与其他调用序列共享的值,但我想在带外(即在调用参数之外)进行此操作,我可能会雇用这样的东西 .

    class MyContextInformation : IDisposable {
        [ThreadStatic] private static MyContextInformation current;
    
        public static MyContextInformation Current {
            get { return current; }
        }
    
        private MyContextInformation previous;
    
    
        public MyContextInformation(Object myData) {
           this.myData = myData;
           previous = current;
           current = this;
        }
    
        public void Dispose() {
           current = previous;
        }
    }
    

    稍后在我的代码中,我可以使用它来向我的代码下游的人提供带外的上下文信息 . 例:

    using(new MyContextInformation(someInfoInContext)) {
       ...
    }
    

    ThreadStatic属性允许我将调用范围仅限于有问题的线程,避免跨线程的数据访问的混乱问题 .

  • 8

    DebuggerHiddenAttribute允许避免步入不应调试的代码 .

    public static class CustomDebug
    {
        [DebuggerHidden]
        public static void Assert(Boolean condition, Func<Exception> exceptionCreator) { ... }
    }
    
    ...
    
    // The following assert fails, and because of the attribute the exception is shown at this line
    // Isn't affecting the stack trace
    CustomDebug.Assert(false, () => new Exception());
    

    它还可以防止在堆栈跟踪中显示方法,当有一个只包装另一个方法的方法时很有用:

    [DebuggerHidden]
    public Element GetElementAt(Vector2 position)
    {
        return GetElementAt(position.X, position.Y);
    }
    
    public Element GetElementAt(Single x, Single y) { ... }
    

    如果现在调用 GetElementAt(new Vector2(10, 10)) 并且在包装方法中发生错误,则调用堆栈不会显示调用抛出错误的方法的方法 .

  • 17

    DesignerSerializationVisibilityAttribute非常有用 . 当您在控件或组件上放置运行时属性,并且您不希望设计器对其进行序列化时,您可以像这样使用它:

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public Foo Bar {
        get { return baz; }
        set { baz = value; }
    }
    
  • 11

    只有少数属性得到编译器的支持,但是AOP中一个非常有趣的属性使用:PostSharp使用你的定制属性将IL注入到方法中,允许所有方式的能力......日志/跟踪是微不足道的例子 - 但是其他一些好的例子像自动INotifyPropertyChanged实现(here) .

    一些发生并直接影响编译器或运行时:

    • [Conditional("FOO")] - 仅在构建期间定义"FOO"符号时才会调用此方法(包括参数评估)

    • [MethodImpl(...)] - 用于表示同步,内联等内容

    • [PrincipalPermission(...)] - 用于自动将安全检查注入代码

    • [TypeForwardedTo(...)] - 用于在不重建调用者的情况下在程序集之间移动类型

    对于通过反射手动检查的东西 - 我是 System.ComponentModel 属性的忠实粉丝;像 [TypeDescriptionProvider(...)][TypeConverter(...)][Editor(...)] 之类的东西可以完全改变数据绑定场景中类型的行为(即动态属性等) .

  • 25

    我最近一直在使用 [DataObjectMethod] . 它描述了该方法,因此您可以将您的类与ObjectDataSource(或其他控件)一起使用 .

    [DataObjectMethod(DataObjectMethodType.Select)] 
    [DataObjectMethod(DataObjectMethodType.Delete)] 
    [DataObjectMethod(DataObjectMethodType.Update)] 
    [DataObjectMethod(DataObjectMethodType.Insert)]
    

    More info

  • 15

    如果我要进行代码覆盖爬行,我认为这两个将是顶级的:

    [Serializable]
     [WebMethod]
    
  • 11

    在我们当前的项目中,我们使用

    [ComVisible(false)]
    

    它控制单个托管类型或成员或程序集中所有类型的可访问性 .

    More Info

  • 25
    [TypeConverter(typeof(ExpandableObjectConverter))]
    

    告诉设计者扩展属性(属于您的控件)

    [Obfuscation]
    

    Instructs obfuscation tools to take the specified actions for an assembly, type, or member.(虽然通常使用装配级 [assembly:ObfuscateAssemblyAttribute(true)]

  • 21

    我最常用的属性是与XML序列化相关的属性 .

    XmlRoot

    XmlElement

    XmlAttribute

    等等...

    在进行任何快速和脏的XML解析或序列化时非常有用 .

  • 95

    作为中间层开发人员,我喜欢

    System.ComponentModel.EditorBrowsableAttribute 允许我隐藏属性,以便UI开发人员不会被他们不需要查看的属性所淹没 .

    System.ComponentModel.BindableAttribute 有些东西不需要数据绑定 . 同样,减少了UI开发人员需要完成的工作 .

    我也喜欢劳伦斯约翰斯顿提到的 DefaultValue .

    System.ComponentModel.BrowsableAttributeFlags 经常使用 .

    我需要时使用 System.STAThreadAttribute System.ThreadStaticAttribute .

    顺便说说 . 我对所有.Net框架开发人员都有同样的 Value .

  • 5

    如果项目不在您的解决方案中, [EditorBrowsable(EditorBrowsableState.Never)] 允许您从IntelliSense隐藏属性和方法 . 对于隐藏流畅接口的无效流非常有用 . 你多久想要GetHashCode()或Equals()?

    对于MVC, [ActionName("Name")] 允许您使用相同的方法签名获取Get动作和Post动作,或者在动作名称中使用破折号,否则在没有为其创建路径的情况下将无法使用破折号 .

  • 126

    我通过CodeSmith生成数据实体类,并使用属性进行某些验证例程 . 这是一个例子:

    /// <summary>
    /// Firm ID
    /// </summary>
    [ChineseDescription("送样单位编号")]
    [ValidRequired()]
    public string FirmGUID
    {
        get { return _firmGUID; }
        set { _firmGUID = value; }
    }
    

    我有一个实用程序类,可以根据附加到数据实体类的属性进行验证 . 这是代码:

    namespace Reform.Water.Business.Common
    {
    /// <summary>
    /// Validation Utility
    /// </summary>
    public static class ValidationUtility
    {
        /// <summary>
        /// Data entity validation
        /// </summary>
        /// <param name="data">Data entity object</param>
        /// <returns>return true if the object is valid, otherwise return false</returns>
        public static bool Validate(object data)
        {
            bool result = true;
            PropertyInfo[] properties = data.GetType().GetProperties();
            foreach (PropertyInfo p in properties)
            {
                //Length validatioin
                Attribute attribute = Attribute.GetCustomAttribute(p,typeof(ValidLengthAttribute), false);
                if (attribute != null)
                {
                    ValidLengthAttribute validLengthAttribute = attribute as ValidLengthAttribute;
                    if (validLengthAttribute != null)
                    {
                        int maxLength = validLengthAttribute.MaxLength;
                        int minLength = validLengthAttribute.MinLength;
                        string stringValue = p.GetValue(data, null).ToString();
                        if (stringValue.Length < minLength || stringValue.Length > maxLength)
                        {
                            return false;
                        }
                    }
                }
                //Range validation
                attribute = Attribute.GetCustomAttribute(p,typeof(ValidRangeAttribute), false);
                if (attribute != null)
                {
                    ValidRangeAttribute validRangeAttribute = attribute as ValidRangeAttribute;
                    if (validRangeAttribute != null)
                    {
                        decimal maxValue = decimal.MaxValue;
                        decimal minValue = decimal.MinValue;
                        decimal.TryParse(validRangeAttribute.MaxValueString, out maxValue);
                        decimal.TryParse(validRangeAttribute.MinValueString, out minValue);
                        decimal decimalValue = 0;
                        decimal.TryParse(p.GetValue(data, null).ToString(), out decimalValue);
                        if (decimalValue < minValue || decimalValue > maxValue)
                        {
                            return false;
                        }
                    }
                }
                //Regex validation
                attribute = Attribute.GetCustomAttribute(p,typeof(ValidRegExAttribute), false);
                if (attribute != null)
                {
                    ValidRegExAttribute validRegExAttribute = attribute as ValidRegExAttribute;
                    if (validRegExAttribute != null)
                    {
                        string objectStringValue = p.GetValue(data, null).ToString();
                        string regExString = validRegExAttribute.RegExString;
                        Regex regEx = new Regex(regExString);
                        if (regEx.Match(objectStringValue) == null)
                        {
                            return false;
                        }
                    }
                }
                //Required field validation
                attribute = Attribute.GetCustomAttribute(p,typeof(ValidRequiredAttribute), false);
                if (attribute != null)
                {
                    ValidRequiredAttribute validRequiredAttribute = attribute as ValidRequiredAttribute;
                    if (validRequiredAttribute != null)
                    {
                        object requiredPropertyValue = p.GetValue(data, null);
                        if (requiredPropertyValue == null || string.IsNullOrEmpty(requiredPropertyValue.ToString()))
                        {
                            return false;
                        }
                    }
                }
            }
            return result;
        }
    }
    }
    
  • 7

    我认为那是这里要提到的是,以下属性也非常重要:

    STAThreadAttribute
    

    表示应用程序的COM线程模型是单线程单元(STA) .

    例如,在Windows窗体应用程序中使用此属性:

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
    

    并且 ...

    SuppressMessageAttribute
    

    禁止报告特定的静态分析工具规则违规,允许对单个代码工件进行多次抑制 .

    例如:

    [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isChecked")]
    [SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "fileIdentifier")]
    static void FileNode(string name, bool isChecked)
    {
        string fileIdentifier = name;
        string fileName = name;
        string version = String.Empty;
    }
    
  • 25

    [System.Security.Permissions.PermissionSetAttribute] 允许使用声明性安全性将PermissionSet的安全性操作应用于代码 .

    // usage:
    public class FullConditionUITypeEditor : UITypeEditor
    {
        // The immediate caller is required to have been granted the FullTrust permission.
        [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
        public FullConditionUITypeEditor() { }
    }
    

相关问题