.NET中的属性是什么?
.NET中的属性是什么,它们有什么好处,以及如何创build我自己的属性?
元数据。 有关您的对象/方法/属性的数据。
例如,我可能会声明一个名为DisplayOrder的属性,这样我可以轻松控制属性在UI中出现的顺序。 然后我可以将它附加到一个类中,并编写一些GUI组件来提取属性并适当地排列UI元素。
public class DisplayWrapper { private UnderlyingClass underlyingObject; public DisplayWrapper(UnderlyingClass u) { underlyingObject = u; } [DisplayOrder(1)] public int SomeInt { get { return underlyingObject .SomeInt; } } [DisplayOrder(2)] public DateTime SomeDate { get { return underlyingObject .SomeDate; } } }
从而确保在使用我的自定义GUI组件时,SomeIate始终显示在SomeDate之前。
不过,你会看到他们最常用的直接编码环境之外。 例如,Windows Designer广泛使用它们,所以它知道如何处理自定义的对象。 像这样使用BrowsableAttribute:
[Browsable(false)] public SomeCustomType DontShowThisInTheDesigner { get{/*do something*/} }
告诉devise者不要在devise时在属性窗口的可用属性中列出这个例子。
您也可以将它们用于代码生成,预编译操作(如Post-Sharp)或运行时操作(如Reflection.Emit)。 例如,你可以写一些分析代码,透明地包装你的代码所做的每一个调用和时间。 您可以通过放置特定方法的属性“select退出”时间。
public void SomeProfilingMethod(MethodInfo targetMethod, object target, params object[] args) { bool time = true; foreach (Attribute a in target.GetCustomAttributes()) { if (a.GetType() is NoTimingAttribute) { time = false; break; } } if (time) { StopWatch stopWatch = new StopWatch(); stopWatch.Start(); targetMethod.Invoke(target, args); stopWatch.Stop(); HandleTimingOutput(targetMethod, stopWatch.Duration); } else { targetMethod.Invoke(target, args); } }
声明它们很简单,只需创build一个从Attributeinheritance的类。
public class DisplayOrderAttribute : Attribute { private int order; public DisplayOrderAttribute(int order) { this.order = order; } public int Order { get { return order; } } }
并且要记住,当你使用属性时,你可以省略后缀“attribute”,编译器会为你添加这个后缀。
很多人已经回答,但目前为止没有人提到这一点。
属性大量使用reflection。 反思已经很慢了。
将自定义属性标记为sealed
类以提高其运行时性能是非常值得的 。
考虑在哪里使用这样一个属性是合适的,并且通过AttributeUsage
来指定你的属性(!)来表明这是一个好主意。 可用的属性用法列表可能会让你大吃一惊:
- 部件
- 模
- 类
- 结构
- 枚举
- 构造函数
- 方法
- 属性
- 领域
- 事件
- 接口
- 参数
- 代表
- 返回值
- 的GenericParameter
- 所有
AttributeUsage属性是AttributeUsage属性签名的一部分,这也很酷。 哇,循环依赖!
[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)] public sealed class AttributeUsageAttribute : Attribute
属性是一种用于标记类的元数据。 这通常在WinForms中用于隐藏工具栏中的控件,但可以在您自己的应用程序中实现,以使不同类的实例能够以特定方式运行。
首先创build一个属性:
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)] public class SortOrderAttribute : Attribute { public int SortOrder { get; set; } public SortOrderAttribute(int sortOrder) { this.SortOrder = sortOrder; } }
所有的属性类必须有后缀“属性”才有效。
完成后,创build一个使用该属性的类。
[SortOrder(23)] public class MyClass { public MyClass() { } }
现在,您可以通过执行以下操作来检查特定类的SortOrderAttribute(如果有):
public class MyInvestigatorClass { public void InvestigateTheAttribute() { // Get the type object for the class that is using // the attribute. Type type = typeof(MyClass); // Get all custom attributes for the type. object[] attributes = type.GetCustomAttributes( typeof(SortOrderAttribute), true); // Now let's make sure that we got at least one attribute. if (attributes != null && attributes.Length > 0) { // Get the first attribute in the list of custom attributes // that is of the type "SortOrderAttribute". This should only // be one since we said "AllowMultiple=false". SortOrderAttribute attribute = attributes[0] as SortOrderAttribute; // Now we can get the sort order for the class "MyClass". int sortOrder = attribute.SortOrder; } } }
如果你想了解更多关于这个,你总是可以看看MSDN有一个很好的描述。
我希望这能帮助你!
属性是一个包含一些function的类,可以将其应用于代码中的对象。 要创build一个,创build一个从System.Attributeinheritance的类。
至于他们有什么好处…他们几乎有无限的用途。
属性类似于应用于类,方法或程序集的元数据。
它们适用于任何数量的东西(debugging器可视化,将事物标记为过时,将事物标记为可序列化,列表无穷无尽)。
创build自己的自定义的很容易。 从这里开始:
http://msdn.microsoft.com/en-us/library/sw480ze8(VS.71).aspx
在我目前正在开发的项目中,有一组各种风格的UI对象和一个编辑器来组装这些对象,以创build在主应用程序中使用的页面,有点像DevStudio中的表单devise器。 这些对象存在于它们自己的程序集中,每个对象都是从UserControl
派生的类,并具有一个自定义属性。 这个属性是这样定义的:
[AttributeUsage (AttributeTargets::Class)] public ref class ControlDescriptionAttribute : Attribute { public: ControlDescriptionAttribute (String ^name, String ^description) : _name (name), _description (description) { } property String ^Name { String ^get () { return _name; } } property String ^Description { String ^get () { return _description; } } private: String ^ _name, ^ _description; };
我把它应用到这样一个类:
[ControlDescription ("Pie Chart", "Displays a pie chart")] public ref class PieControl sealed : UserControl { // stuff };
这是以前的海报所说的。
要使用该属性,编辑器具有包含控件types的Generic::List <Type>
。 有一个列表框让用户可以拖放到页面上来创build控件的一个实例。 为了填充列表框,我得到控件的ControlDescriptionAttribute
,并在列表中填写一个条目:
// done for each control type array <Object ^> // get all the custom attributes ^attributes = controltype->GetCustomAttributes (true); Type // this is the one we're interested in ^attributetype = ECMMainPageDisplay::ControlDescriptionAttribute::typeid; // iterate over the custom attributes for each (Object ^attribute in attributes) { if (attributetype->IsInstanceOfType (attribute)) { ECMMainPageDisplay::ControlDescriptionAttribute ^description = safe_cast <ECMMainPageDisplay::ControlDescriptionAttribute ^> (attribute); // get the name and description and create an entry in the list ListViewItem ^item = gcnew ListViewItem (description->Name); item->Tag = controltype->Name; item->SubItems->Add (description->Description); mcontrols->Items->Add (item); break; } }
注意:以上是C ++ / CLI但是转换为C#并不困难(是的,我知道,C ++ / CLI是一种憎恶,但这是我必须使用的:-()
您可以将属性放在大多数事物上,并且有一系列预定义的属性。 上面提到的编辑器还查找属性的自定义属性,以描述属性以及如何编辑它。
一旦你得到了全部的想法,你会想知道你没有他们的生活。
如前所述,属性相对容易创build。 另一部分工作是创build使用它的代码。 在大多数情况下,您将在运行时使用reflection来基于属性或属性的存在来改变行为。 还有一些情况,你将检查编译代码的属性做一些静态分析。 例如,参数可能被标记为非空,分析工具可以将其用作提示。
大部分的工作是使用这些属性,并了解它们的使用情况。
属性本质上是你想要附加到你的types (类,方法,事件,枚举等)
这个想法是,在运行时,一些其他types/框架/工具将查询您的types的属性信息,并采取行动。
因此,例如,Visual Studio可以查询第三方控件上的属性,以确定控件的哪些属性应该在devise时显示在“属性”窗格中。
在面向方面编程中也可以使用属性来在运行时基于装饰它们的属性注入/操作对象,并在不影响对象的业务逻辑的情况下向对象添加validation,日志等。
您可以使用自定义属性作为在子类中定义标记值的简单方法,而不必为每个子类重复编写相同的代码。 我遇到了约翰·沃特斯(John Waters)提供的一个很好的简明例子,他说明如何在自己的代码中定义和使用自定义属性
有一个教程在http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx
要开始创build属性,请打开C#源文件,inputattribute
然后按[TAB]。 它将扩展为一个新的属性模板。
属性也常用于面向方面编程。 对于这个例子来看看PostSharp项目。