.NET中的属性是什么,它们有什么好处,我如何创建自己的属性?
当前回答
元数据。关于对象/方法/属性的数据。
例如,我可以声明一个名为:DisplayOrder的属性,这样我就可以很容易地控制属性应该在UI中出现的顺序。然后,我可以将它附加到一个类中,并编写一些提取属性并对UI元素进行适当排序的GUI组件。
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设计器广泛使用它们,因此它知道如何处理自定义对象。像这样使用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”,编译器会为你添加。
NOTE: Attributes don't do anything by themselves - there needs to be some other code that uses them. Sometimes that code has been written for you but sometimes you have to write it yourself. For example, the C# compiler cares about some and certain frameworks frameworks use some (e.g. NUnit looks for [TestFixture] on a class and [Test] on a test method when loading an assembly). So when creating your own custom attribute be aware that it will not impact the behaviour of your code at all. You'll need to write the other part that checks attributes (via reflection) and act on them.
其他回答
在我目前从事的项目中,有一组不同风格的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是一个讨厌的东西,但它是我必须使用的:-()
你可以把属性放在大多数东西上,有一整套预定义的属性。上面提到的编辑器还会在描述属性以及如何编辑属性的属性上查找自定义属性。
一旦你明白了它们的全部含义,你就会想,没有它们你是怎么生活的。
元数据。关于对象/方法/属性的数据。
例如,我可以声明一个名为:DisplayOrder的属性,这样我就可以很容易地控制属性应该在UI中出现的顺序。然后,我可以将它附加到一个类中,并编写一些提取属性并对UI元素进行适当排序的GUI组件。
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设计器广泛使用它们,因此它知道如何处理自定义对象。像这样使用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”,编译器会为你添加。
NOTE: Attributes don't do anything by themselves - there needs to be some other code that uses them. Sometimes that code has been written for you but sometimes you have to write it yourself. For example, the C# compiler cares about some and certain frameworks frameworks use some (e.g. NUnit looks for [TestFixture] on a class and [Test] on a test method when loading an assembly). So when creating your own custom attribute be aware that it will not impact the behaviour of your code at all. You'll need to write the other part that checks attributes (via reflection) and act on them.
要开始创建一个属性,打开一个c#源文件,输入attribute并点击[TAB]。它将展开为一个新属性的模板。
很多人都回答了,但到目前为止还没有人提到这个问题……
属性与反射一起被大量使用。反射已经相当慢了。
将自定义属性标记为密封类以提高其运行时性能是非常值得的。
考虑在哪里使用place这样的属性是合适的,并通过AttributeUsage来指定属性(!),这也是一个好主意。可用属性用法的列表可能会让你大吃一惊:
组装 模块 类 结构体 枚举 构造函数 方法 财产 场 事件 接口 参数 委托 ReturnValue GenericParameter 所有
AttributeUsage属性是AttributeUsage属性签名的一部分,这也很酷。哇,循环依赖!
[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)]
public sealed class AttributeUsageAttribute : Attribute
属性就像应用于类、方法或程序集的元数据。
它们适用于任何数量的事情(调试器可视化,标记为过时的东西,标记为可序列化的东西,列表是无限的)。
创建您自己的自定义是很容易的。从这里开始:
http://msdn.microsoft.com/en-us/library/sw480ze8 (VS.71) . aspx
推荐文章
- 我如何使一个方法的返回类型泛型?
- 何时处理CancellationTokenSource?
- 如何获取正在执行的程序集版本?
- AutoMapper vs valueinjector
- 为什么控制台不。Writeline,控制台。在Visual Studio Express中编写工作?
- 什么是.NET程序集?
- 字符串不能识别为有效的日期时间“格式dd/MM/yyyy”
- 函数应该返回空对象还是空对象?
- 如何转换日期时间?将日期时间
- 如何在c#中连接列表?
- 在c#中引用类型变量的“ref”的用途是什么?
- 防止在ASP中缓存。NET MVC中使用属性的特定操作
- 转换为值类型'Int32'失败,因为物化值为空
- c#中有任何连接字符串解析器吗?
- 在Linq中转换int到字符串到实体的问题