最有用的属性

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

您在项目中实际使用的预定义属性(及其命名空间)是什么?

168752 次浏览

[Serializable]一直用于与外部数据源(如xml或远程服务器)之间的对象序列化和反序列化。更多关于它在这里。

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

莱普指出了一些我没有意识到的事情,这相当抑制了我对这个属性的热情:它确实没有指示编译器允许位组合作为枚举变量的有效值,编译器允许枚举无论如何。我的C++背景显示通过…叹息

如果我要做代码覆盖率爬行,我认为这两个会是最重要的:

 [Serializable][WebMethod]

在Hofstadtian精神中,[Attribute]属性非常有用,因为它是您创建自己属性的方式。我使用属性而不是接口来实现插件系统、向Enums添加描述、模拟多个调度和其他技巧。

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

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

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

不管它值多少钱,这里是所有. NET属性的列表。有几百个。

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

我发现[DefaultValue]非常有用。

当您在调试期间将鼠标放在Type的实例上时,[DebuggerDisplay]对于快速查看Type的自定义输出非常有帮助。例子:

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

这是它在调试器中的样子:

alt文本

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

我建议[TestFixture][Test]-从nUnit库。

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

我喜欢#0系统诊断

这对于避免进入那些单行无用的方法或属性非常方便(如果你被迫在没有自动属性的早期. Net中工作)。将属性放在短方法或属性的getter或setter上,即使在调试器中点击“单步进入”,你也会直接通过。

作为我喜欢的中间层开发者

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

System.ComponentModel.BindableAttribute有些事情不需要数据库。同样,减少了UI开发人员需要做的工作。

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

System.ComponentModel.BrowsableAttributeFlags经常使用。

我用System.STAT线程属性系统。线程静态属性需要的时候

顺便说一下,这些对所有. Net框架开发人员来说都是有价值的。

我使用最多的属性是与XML序列化相关的属性。

XmlRoot

XmlElement

XmlAttribute

等…

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

只有少数属性得到编译器的支持,但属性的一个非常有趣的用法是在AOP中:PostSharp使用您定制的属性将IL注入到方法中,允许各种能力……日志/跟踪是琐碎的例子——但其他一些好的例子是自动INotifyProperties tyChanged实现(这里)。

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

  • [Conditional("FOO")]-只有在构建期间定义了“FOO”符号时才会调用此方法(包括参数求值)
  • [MethodImpl(...)]-用于表示一些事情,例如同步、内联
  • [PrincipalPermission(...)]-用于自动将安全检查注入代码
  • [TypeForwardedTo(...)]-用于在程序集之间移动类型没有重建来电者

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

[TypeConverter(typeof(ExpandableObjectConverter))]

告诉设计器扩展作为类(您的控件)的属性

[Obfuscation]

指示混淆工具对程序集、类型或成员执行指定操作。(虽然通常使用汇编级别[assembly:ObfuscateAssemblyAttribute(true)]

[XmlIgnore]

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

// on configuration sections[ConfigurationProperty]
// in asp.net[NotifyParentProperty(true)]

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

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

更多信息

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

[ComVisible(false)]

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

更多信息

我喜欢将[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属性允许我将调用范围仅限于有问题的线程,避免了跨线程访问数据的混乱问题。

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

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

我总是在我的用户控件、自定义控件或我将通过属性网格编辑的任何类的公共属性上使用DisplayNameDescriptionDefaultValue属性。这些标签由. NET属性网格用于格式化名称、描述面板和未设置为默认值的粗体值。

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

我只是希望Visual Studio的IntelliSense在没有找到XML注释的情况下考虑Description属性。它将避免重复同一个句子两次。

[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() { }}

这里是关于有趣属性内部显示的帖子。基本上它模仿了C++朋友的访问功能。它对于单元测试非常方便。

我的投票是Conditional

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

您可以使用它来添加具有高级调试功能的函数;与Debug.Write一样,它仅在调试构建中调用,因此允许您在程序的主流程之外封装复杂的调试逻辑。

它没有很好的命名,在框架中没有得到很好的支持,也不应该需要参数,但这个属性是不可变类的有用标记:

[ImmutableObject(true)]

[DeploymentItem("myFile1.txt")]MSDN文档on DeploymentItem

如果您针对文件进行测试或将该文件用作测试的输入,这非常有用。

我通过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 validatioinAttribute 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 validationattribute = 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 validationattribute = 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 validationattribute = 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;}}}

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

标志,可序列化,Web方法,COMViable,TypeConver,条件,线程静态,过时,内部可见到,调试器逐步通过。

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

对于MVC[ActionName("Name")],您可以拥有具有相同方法签名的Get操作和Post操作,或者在操作名称中使用破折号,否则如果不为其创建路由,则无法实现。

我总是使用属性,[Serializable][WebMethod][DefaultValue][Description("description here")].

但是在C#中有一个全局属性

[assembly: System.CLSCompliant(true)][assembly: AssemblyCulture("")][assembly: AssemblyDescription("")]

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

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

调试器隐藏属性允许避免进入不应调试的代码。

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 traceCustomDebug.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))并且包装方法发生错误,则调用堆栈不会显示正在调用抛出错误的方法的方法。