C# .NET 中的属性是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20346/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-01 09:06:09  来源:igfitidea点击:

What are attributes in .NET?

提问by Corey

What are attributes in .NET, what are they good for, and how do I create my own attributes?

.NET 中的属性是什么,它们有什么用处,以及如何创建自己的属性?

采纳答案by Quibblesome

Metadata. Data about your objects/methods/properties.

元数据。关于您的对象/方法/属性的数据。

For example I might declare an Attribute called: DisplayOrder so I can easily control in what order properties should appear in the UI. I could then append it to a class and write some GUI components that extract the attributes and order the UI elements appropriately.

例如,我可能会声明一个名为: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;
        }
    }
}

Thereby ensuring that SomeInt is always displayed before SomeDate when working with my custom GUI components.

从而确保在使用我的自定义 GUI 组件时 SomeInt 始终显示在 SomeDate 之前。

However, you'll see them most commonly used outside of the direct coding environment. For example the Windows Designer uses them extensively so it knows how to deal with custom made objects. Using the BrowsableAttribute like so:

但是,您会看到它们在直接编码环境之外最常用。例如,Windows 设计器广泛使用它们,因此它知道如何处理自定义对象。像这样使用 BrowsableAttribute:

[Browsable(false)]
public SomeCustomType DontShowThisInTheDesigner
{
    get{/*do something*/}
}

Tells the designer not to list this in the available properties in the Properties window at design time for example.

例如,告诉设计者不要在设计时将其列在“属性”窗口的可用属性中。

You couldalso use them for code-generation, pre-compile operations (such as Post-Sharp) or run-time operations such as Reflection.Emit. For example, you could write a bit of code for profiling that transparently wrapped every single call your code makes and times it. You could "opt-out" of the timing via an attribute that you place on particular methods.

可能还使用它们生成代码,预编译操作(如后夏普)或运行时操作如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);
    }
}

Declaring them is easy, just make a class that inherits from Attribute.

声明它们很容易,只需创建一个继承自 Attribute 的类即可。

public class DisplayOrderAttribute : Attribute
{
    private int order;

    public DisplayOrderAttribute(int order)
    {
        this.order = order;
    }

    public int Order
    {
        get { return order; }
    }
}

And remember that when you use the attribute you can omit the suffix "attribute" the compiler will add that for you.

请记住,当您使用属性时,您可以省略后缀“属性”,编译器会为您添加它。

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# 编译器关心某些和某些框架使用某些框架(例如,NUnit 在加载程序集时在类上查找 [TestFixture],在测试方法上查找 [Test])。
因此,在创建您自己的自定义属性时,请注意它根本不会影响您的代码的行为。您需要编写检查属性(通过反射)并对其进行操作的另一部分。

回答by TheSmurf

An attribute is a class that contains some bit of functionality that you can apply to objects in your code. To create one, create a class that inherits from System.Attribute.

属性是一个包含一些功能的类,您可以将这些功能应用于代码中的对象。要创建一个,请创建一个继承自 System.Attribute 的类。

As for what they're good for... there are almost limitless uses for them.

至于它们的用途……它们的用途几乎是无限的。

http://www.codeproject.com/KB/cs/dotnetattributes.aspx

http://www.codeproject.com/KB/cs/dotnetattributes.aspx

回答by Stu

Attributes are like metadata applied to classes, methods or assemblies.

属性就像应用于类、方法或程序集的元数据。

They are good for any number of things (debugger visualization, marking things as obsolete, marking things as serializable, the list is endless).

它们适用于任何数量的事物(调试器可视化,将事物标记为过时,将事物标记为可序列化,列表是无止境的)。

Creating your own custom ones is easy as pie. Start here:

创建您自己的自定义对象很容易。从这里开始:

http://msdn.microsoft.com/en-us/library/sw480ze8(VS.71).aspx

http://msdn.microsoft.com/en-us/library/sw480ze8(VS.71).aspx

回答by Chris Miller

You can use custom attributes as a simple way to define tag values in sub classes without having to write the same code over and over again for each subclass. I came across a nice concise example by John Watersof how to define and use custom attributes in your own code.

您可以使用自定义属性作为在子类中定义标签值的简单方法,而不必为每个子类一遍又一遍地编写相同的代码。我遇到了John Waters的一个很好的简洁示例,示例介绍了如何在您自己的代码中定义和使用自定义属性。

There is a tutorial at http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx

http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx 上有一个教程

回答by Patrik Svensson

Attributes are a kind of meta data for tagging classes. This is often used in WinForms for example to hide controls from the toolbar, but can be implemented in your own application to enable instances of different classes to behave in specific ways.

属性是一种用于标记类的元数据。这通常在 WinForms 中使用,例如从工具栏中隐藏控件,但可以在您自己的应用程序中实现,以使不同类的实例以特定方式运行。

Start by creating an attribute:

首先创建一个属性:

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
public class SortOrderAttribute : Attribute
{
    public int SortOrder { get; set; }

    public SortOrderAttribute(int sortOrder)
    {
        this.SortOrder = sortOrder;
    }
}

All attribute classes must have the suffix "Attribute" to be valid.
After this is done, create a class that uses the attribute.

所有属性类都必须具有后缀“Attribute”才能有效。
完成此操作后,创建一个使用该属性的类。

[SortOrder(23)]
public class MyClass
{
    public MyClass()
    {
    }
}

Now you can check a specific class' SortOrderAttribute(if it has one) by doing the following:

现在,您可以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;
        }
    }
}

If you want to read more about this you can always check out MSDNwhich has a pretty good description.
I hope this helped you out!

如果你想阅读更多关于这方面的信息,你可以随时查看MSDN,它有一个很好的描述。
我希望这对你有帮助!

回答by denis phillips

As said, Attributes are relatively easy to create. The other part of the work is creating code that uses it. In most cases you will use reflection at runtime to alter behavior based on the presence of an attribute or its properties. There are also scenarios where you will inspect attributes on compiled code to do some sort of static analysis. For example, parameters might be marked as non-null and the analysis tool can use this as a hint.

如前所述,属性相对容易创建。工作的另一部分是创建使用它的代码。在大多数情况下,您将在运行时使用反射来根据属性或其属性的存在来改变行为。在某些情况下,您将检查已编译代码的属性以进行某种静态分析。例如,参数可能被标记为非空,分析工具可以将其用作提示。

Using the attributes and knowing the appropriate scenarios for their use is the bulk of the work.

使用属性并了解使用它们的适当场景是大部分工作。

回答by Skizz

In the project I'm currently working on, there is a set of UI objects of various flavours and an editor to assembly these objects to create pages for use in the main application, a bit like the form designer in DevStudio. These objects exist in their own assembly and each object is a class derived from UserControland has a custom attribute. This attribute is defined like this:

在我目前正在进行的项目中,有一组各种风格的 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;
};

and I apply it to a class like this:

我将它应用于这样的类:

[ControlDescription ("Pie Chart", "Displays a pie chart")]
public ref class PieControl sealed : UserControl
{
  // stuff
};

which is what the previous posters have said.

这就是之前的海报所说的。

To use the attribute, the editor has a Generic::List <Type>containing the control types. There is a list box which the user can drag from and drop onto the page to create an instance of the control. To populate the list box, I get the ControlDescriptionAttributefor the control and fill out an entry in the list:

要使用该属性,编辑器有一个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;
  }
}

Note: the above is C++/CLI but it's not difficult to convert to C# (yeah, I know, C++/CLI is an abomination but it's what I have to work with :-( )

注意:以上是 C++/CLI,但转换为 C# 并不难(是的,我知道,C++/CLI 是一种令人憎恶的东西,但这是我必须使用的 :-()

You can put attributes on most things and there are whole range of predefined attributes. The editor mentioned above also looks for custom attributes on properties that describe the property and how to edit it.

您可以在大多数事物上放置属性,并且有整个范围的预定义属性。上面提到的编辑器还会在属性上查找描述属性以及如何编辑它的自定义属性。

Once you get the whole idea, you'll wonder how you ever lived without them.

一旦你明白了整个想法,你会想知道没有它们你是如何生活的。

回答by urini

Attributes are, essentially, bits of data you want to attach to your types(classes, methods, events, enums, etc.)

属性本质上是您想要附加到您的类型(类、方法、事件、枚举等)的数据位。

The idea is that at run time some other type/framework/tool will query yourtype for the information in the attribute and act upon it.

这个想法是在运行时一些其他类型/框架/工具将查询您的类型以获取属性中的信息并对其采取行动。

So, for example, Visual Studio can query the attributes on a 3rd party control to figure out which properties of the control should appear in the Properties pane at design time.

因此,例如,Visual Studio 可以查询第 3 方控件上的属性,以确定控件的哪些属性应在设计时出现在“属性”窗格中。

Attributes can also be used in Aspect Oriented Programming to inject/manipulate objects at run time based on the attributes that decorate them and add validation, logging, etc. to the objects without affecting the business logic of the object.

属性也可以在面向切面编程中用于在运行时根据修饰对象的属性注入/操作对象,并在不影响对象业务逻辑的情况下向对象添加验证、日志记录等。

回答by Jay Bazuzi

To get started creating an attribute, open a C# source file, type attributeand hit [TAB]. It will expand to a template for a new attribute.

要开始创建属性,请打开 C# 源文件,键入attribute并点击 [TAB]。它将扩展为新属性的模板。

回答by Drew Noakes

Many people have answered but no one has mentioned this so far...

很多人已经回答了,但到目前为止没有人提到这一点......

Attributes are used heavily with reflection. Reflection is already pretty slow.

属性在反射中被大量使用。反射已经很慢了。

It is very worthwhilemarking your custom attributes as being sealedclasses to improve their runtime performance.

这是非常值得的标记您的自定义属性为sealed班提高自己的运行时性能。

It is also a good idea to consider where it would be appropriate to use place such an attribute, and to attribute your attribute (!) to indicate this via AttributeUsage. The list of available attribute usages might surprise you:

考虑在何处使用 place 这样的属性是合适的,并将您的属性 (!) 赋予属性以通过AttributeUsage. 可用的属性用法列表可能会让您感到惊讶:

  • Assembly
  • Module
  • Class
  • Struct
  • Enum
  • Constructor
  • Method
  • Property
  • Field
  • Event
  • Interface
  • Parameter
  • Delegate
  • ReturnValue
  • GenericParameter
  • All
  • 集会
  • 模块
  • 班级
  • 结构
  • 枚举
  • 构造函数
  • 方法
  • 财产
  • 场地
  • 事件
  • 界面
  • 范围
  • 代表
  • 返回值
  • 通用参数
  • 全部

It's also cool that the AttributeUsage attribute is part of the AttributeUsage attribute's signature. Whoa for circular dependencies!

AttributeUsage 属性是 AttributeUsage 属性签名的一部分也很酷。哇哦,循环依赖!

[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)]
public sealed class AttributeUsageAttribute : Attribute