简体   繁体   English

在dotnet / .NET中实现自定义属性的最佳方法是什么?

[英]What's the best way to implement custom attributes in dotnet/.NET?

I don't really understand attributes. 我真的不懂属性。 I've read all kinds of books & posts on them, but I just don't get it. 我已经阅读了各种各样的书籍和帖子,但我只是不明白。

Since I don't understand them, I also don't understand how to effectively use them. 由于我不理解它们,我也不明白如何有效地使用它们。

1) Can you give me a good definition of what an attribute is & what it's used for? 1)你能给我一个很好的定义属性是什么以及它用于什么?

2) Can you give me a good code example in C# of how to make and consume a custom attribute? 2)你能在C#中给我一个如何制作和使用自定义属性的好代码示例吗?

I could give you an example but it would pale in comparison to this fine article: 我可以给你一个例子,但与这篇好文章相比,它会变得苍白:

Defining and Using Custom Attribute Classes in C# 在C#中定义和使用自定义属性类

The complex, component-style development that businesses expect out of modern software developers requires greater design flexibility than the design methodologies of the past. 企业期望从现代软件开发人员那里获得的复杂的组件式开发需要比过去的设计方法更大的设计灵活性。 Microsoft's .NET Framework makes extensive use of attributes to provide added functionality through what is known as "declarative" programming. Microsoft的.NET Framework广泛使用属性,通过所谓的“声明性”编程提供附加功能。 Attributes enhance flexibility in software systems because they promote loose coupling of functionality. 属性增强了软件系统的灵活性,因为它们促进了功能的松散耦合。 Because you can create your own custom attribute classes and then act upon them, you can leverage the loose coupling power of attributes for your own purposes. 因为您可以创建自己的自定义属性类然后对它们进行操作,所以您可以利用属性的松散耦合功能来实现自己的目的。

Say you've got a class with a series of properties that you are going to walk through using reflection. 假设您有一个具有一系列属性的类,您将使用反射来完成这些属性。 Any that are strings may need to be validated to check they are not longer than a certain amount. 任何字符串都可能需要验证,以检查它们是否不超过一定数量。

You could then create a TextLength attribute, with a default integer constructor and integer property/field. 然后,您可以使用默认的整数构造函数和整数属性/字段创建TextLength属性。 You could then read your attribute on each string property in your class and compare the length of the property value to the number specified in the attribute. 然后,您可以在类中的每个字符串属性上读取属性,并将属性值的长度与属性中指定的数字进行比较。

Code: 码:

public class TextLengthAttribute : Attribute
{
    private int length;
    public int Length { get { return length; } set { length = value; } }

    public TextLengthAttribute(int num) { this.length = num; }
}

public class MyClass
{
    [TextLength(10)]
    public string Property1;
    [TextLength(20)]
    public string Property2;
}

public class ClassReader
{
     public static void Main()
     {
          MyClass example = MyClass.GetTestData();

          PropertyInfo[] props = typeof(MyClass).GetProperties();
          foreach (PropertyInfo prop in props)
          {
               if (prop.ValueType == typeof(String) 
               {
                    TextLengthAttribute[] atts = 
                      (TextLengthAttribute)[]prop.GetCustomAttributes(
                           typeof(TextLengthAttribute), false);
                    if (prop.GetValue(example, null).ToString().Length > 
                         atts[0].Length) 
                        throw new Exception(prop.name + " was too long");
               }
          }
     }
}

Note: untested 注意:未经测试

We have a requirement to display Enum Values in a dropdown in a specific sort order. 我们要求在特定排序顺序的下拉列表中显示枚举值。 We implemented using Custom Attributes. 我们使用自定义属性实现。

[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field, AllowMultiple = false)]
public class EnumSortAttribute : Attribute
{
    public int SortOrder;
    public bool SortByDescription;
}

[EnumSort(SortByDescription=true)]
public enum EnumSortByDescription
{
    [Description("enO")]
    One = 1,
    [Description("2")]
    Two = 2,
    Three = 3,
    [Description("rouF")]
    Four = 4
}

public enum EnumCustomSortOrder
{
    [EnumSort(SortOrder = 3)]
    One = 1,
    [EnumSort(SortOrder = 1)]
    Two = 2,
    [EnumSort(SortOrder = 2)]
    Three = 3
}

Have a lot at eg log4PostSharp . 有很多例如log4PostSharp They use attributes to introduce AOP behaviour. 他们使用属性来引入AOP行为。

That's an attribute I used once, to give properties a unit (like seconds, meter, ...) 这是我用过一次的属性,给属性一个单位(比如秒,米,......)

[AttributeUsage( AttributeTargets.Property )]
public sealed class UnitAttribute : Attribute
{
  public UnitAttribute( Unit unit )
  {
    Unit = unit;
  }

  public Unit Unit { get; private set; }
}

It was used on properties, like this: 它用于属性,如下所示:

[Unit( Unit.Meter )]
public float Distance { get; set; }

You can later retrieve the attribute to show it on the GUI. 您可以稍后检索该属性以在GUI上显示它。

An attribute is used to provide meta data about any member (fields, class etc). 属性用于提供有关任何成员(字段,类等)的元数据。

You can create them by inheriting from Attribute , and consume them by using the Attribute.GetCustomAttribute method. 您可以通过继承Attribute来创建它们,并使用Attribute.GetCustomAttribute方法来使用它们。

An example of a default attribute is the PrincipalPermissionAttribute which only allows authenticated users to access certain resources. PrincipalPermissionAttribute是一个默认属性的示例,它仅允许经过身份验证的用户访问某些资源。 For example: 例如:

[PrincipalPermission (SecurityAction.Demand, Role="Supervisor")]
public class DoTheThingPage : Page
{
    ////
}

In this example, we have an ASP.NET page that can only be viewed by an authenticated user that belongs to the 'Supervisor' role. 在此示例中,我们有一个ASP.NET页面,只能由属于“Supervisor”角色的经过身份验证的用户查看。

(This attribute is automatically read by the security sub-system in ASP.NET) (此属性由ASP.NET中的安全子系统自动读取)

Also note that the 'Attribute' part of the class name wasn't used, it's a convention within .NET. 另请注意,未使用类名的“属性”部分,这是.NET中的约定。

Attribute is just a way to add additional information (metadata) to the class, struct or some member. 属性只是向类,结构或某些成员添加附加信息(元数据)的一种方法。 This meta-data could be retrieved by other code in order to make some decisions. 其他代码可以检索此元数据以做出一些决定。

Simplest example is SerializableAttribute from the .NET. 最简单的例子是来自.NET的SerializableAttribute It indicates that the class could be serialized by a BinaryFormatter later on. 它表示稍后可以通过BinaryFormatter序列化该类。

Here's another example - we could mark some classes in our code with ImmutableAttribute to indicate that they don't have any mutable fields and are OK for multi-threaded operations: 这是另一个例子 - 我们可以使用ImmutableAttribute在代码中标记一些类,以指示它们没有任何可变字段,并且可以用于多线程操作:

[Immutable]
public sealed class ProcessingMessage
{
    //... some code that should be thread-safe

}

Then, we could create a unit test that finds all classes with the attribute and ensures that they are immutable indeed : 然后,我们可以创建一个单元测试,找到具有该属性的所有类,并确保它们确实是不可变的

[Test]
public void Immutable_Types_Should_Be_Immutable()
{
  var decorated = GlobalSetup.Types
    .Where(t => t.Has<ImmutableAttribute>());

  foreach (var type in decorated)
  {
    var count = type.GetAllFields().Count(f => !f.IsInitOnly && !f.IsStatic);
    Assert.AreEqual(0, count, "Type {0} should be immutable", type);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 .NET - 实现“捕获所有异常处理程序”的最佳方法是什么 - .NET - What's the best way to implement a “catch all exceptions handler” 在dotnet core中在运行时实现接口的最佳方法是什么? - What is the best way to implement an interface at runtime in dotnet core? 实施搜索的最佳方法是什么? - What's the best way to implement a search? 为ASP.NET MVC Intranet应用程序实施Windows身份验证的最佳方法是什么? - What's the best way to implement Windows Authentication for an ASP.NET MVC intranet application? 在多租户.net项目中实现角色的最佳方法是什么? - What's the best way to implement roles in a multi-tenant .net project? 在C#.NET中实现不固定的多deminsional数组的最佳方法是什么? - What's the best way to implement an unfixed multi-deminsional array in C#.NET? 实现.NET Wall in .NET等线程会话的最佳方法是什么? - What's the best way to implement threaded conversations like the Facebook Wall in .NET? 在基于DLL更改的.NET项目中实现缓存清除的最佳方法是什么? - What's the best way to implement cache busting in a .NET project based on DLL changes? 熟悉.NET - 最好的方法是什么? - Getting familiar with .NET - What's the best way? 实现自定义剪贴板的最佳方法/数据结构是什么? - What is the best way/data structure to implement a custom Clipboard?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM