.NET中的属性是什么?
.NET中的属性是什么,它们有什么用,以及如何创建自己的属性?
解决方案
回答
属性是一个包含一些功能的类,我们可以将这些功能应用于代码中的对象。要创建一个类,请创建一个继承自System.Attribute的类。
至于它们的优点……它们几乎有无限的用途。
http://www.codeproject.com/KB/cs/dotnetattributes.aspx
回答
属性就像应用于类,方法或者程序集的元数据。
它们对许多事物都有好处(调试器可视化,将事物标记为过时,将事物标记为可序列化,列表无穷无尽)。
创建自己的自定义项很容易。从这里开始:
http://msdn.microsoft.com/zh-CN/library/sw480ze8(VS.71).aspx
回答
我们可以使用自定义属性作为在子类中定义标签值的简单方法,而不必为每个子类一遍又一遍地编写相同的代码。我遇到了约翰·沃特斯(John Waters)一个简洁的示例,它讲述了如何在自己的代码中定义和使用自定义属性。
在http://msdn.microsoft.com/zh-cn/library/aa288454(VS.71).aspx上有一个教程。
回答
元数据。有关对象/方法/属性的数据。
例如,我可以声明一个名为: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组件时,始终将SomeInt显示在SomeDate之前。
但是,我们将看到它们在直接编码环境之外最常用。例如,Windows Designer广泛使用它们,因此它知道如何处理自定义对象。像这样使用BrowsableAttribute:
[Browsable(false)] public SomeCustomType DontShowThisInTheDesigner { get{/*do something*/} }
例如,告诉设计人员不要在设计时在"属性"窗口的可用属性中列出该属性。
我们也可以将它们用于代码生成,预编译操作(如Post-Sharp)或者运行时操作(如Reflection.Emit)。
例如,我们可以编写一些用于性能分析的代码,以透明方式包装代码进行的每个调用并对其计时。我们可以通过在特定方法上放置的属性来"选择退出"计时。
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); } }
声明它们很容易,只需创建一个从Attribute继承的类即可。
public class DisplayOrderAttribute : Attribute { private int order; public DisplayOrderAttribute(int order) { this.order = order; } public int Order { get { return order; } } }
请记住,当我们使用属性时,可以省略后缀" attribute",编译器将为我们添加该属性。
回答
属性是用于标记类的一种元数据。例如,这通常在WinForms中用于从工具栏隐藏控件,但是可以在我们自己的应用程序中实现,以使不同类的实例以特定方式运行。
首先创建一个属性:
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)] public class SortOrderAttribute : Attribute { public int SortOrder { get; set; } public SortOrderAttribute(int sortOrder) { this.SortOrder = sortOrder; } }
所有属性类都必须带有后缀" Attribute"才能有效。
完成此操作后,创建一个使用该属性的类。
[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,它具有很好的描述。
希望这对我们有所帮助!
回答
如前所述,属性相对容易创建。工作的另一部分是创建使用它的代码。在大多数情况下,我们将在运行时使用反射根据属性或者其属性的存在来更改行为。在某些情况下,我们将检查编译后代码的属性以进行某种静态分析。例如,参数可能被标记为非空,分析工具可以将其用作提示。
使用属性并了解使用它们的适当方案是大部分工作。
回答
在我目前正在从事的项目中,有一组各种口味的UI对象和一个编辑器来组合这些对象以创建供主应用程序使用的页面,有点像DevStudio中的表单设计器。这些对象存在于它们自己的程序集中,并且每个对象都是派生自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 };
这就是以前的海报所说的。
要使用该属性,编辑器有一个包含控件类型的Generic :: List <Type>
。有一个列表框,用户可以将其从页面上拖放到页面上以创建控件的实例。为了填充列表框,我获取控件的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是可憎的,但这是我必须使用的:-()
我们可以在大多数事物上放置属性,并且有很多预定义的属性。上面提到的编辑器还在属性上寻找自定义属性,这些属性描述了属性以及如何对其进行编辑。
一旦有了完整的想法,我们就会想知道没有它们,我们将如何生活。
回答
本质上,属性是要添加到类型上的数据位(类,方法,事件,枚举等)。
这个想法是,在运行时,其他一些类型/框架/工具会在类型中查询属性中的信息并对其执行操作。
因此,例如,Visual Studio可以查询第三方控件上的属性,以弄清楚该控件的哪些属性应在设计时显示在"属性"窗格中。
属性也可以在面向方面的编程中使用,以便在运行时基于装饰对象的属性并在不影响对象业务逻辑的情况下向对象添加验证,日志记录等属性。
回答
要开始创建属性,请打开Csource文件,键入attribute
并点击[TAB]。它将扩展为新属性的模板。
回答
到目前为止,很多人都回答了,但没有人提及。
属性与反射一起大量使用。反思已经相当缓慢。
将自定义属性标记为"密封"类以提高其运行时性能是非常值得的。
考虑在适当的地方使用这样的属性,并通过" AttributeUsage"将属性(!)表示为属性,也是一个好主意。可用属性用法列表可能会让我们感到惊讶:
- 部件
- 模块
- 班级
- 结构
- 枚举
- 建设者
- 方法
- 财产
- 场地
- 事件
- 界面
- 范围
- 代表
- 返回值
- 通用参数
- 全部
AttributeUsage属性是AttributeUsage属性签名的一部分也是很酷的。循环依赖的哇!
[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)] public sealed class AttributeUsageAttribute : Attribute
回答
属性也常用于面向方面的编程。有关此示例,请查看PostSharp项目。