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

C# 什么';在dotnet/.NET中实现自定义属性的最佳方法是什么?,c#,.net,attributes,C#,.net,Attributes,我真的不懂属性。我读过各种各样的书和关于它们的帖子,但我就是不明白 因为我不理解它们,我也不知道如何有效地使用它们 1) 你能给我一个关于属性是什么以及它的用途的好定义吗 2) 你能给我一个很好的C语言代码示例,说明如何创建和使用自定义属性吗?有很多例子,例如。它们使用属性来引入AOP行为 这是我曾经使用过的一个属性,用来给属性一个单位(比如秒、米等) 它用于属性,如下所示: [Unit( Unit.Meter )] public float Distance { get; set; } 您可

我真的不懂属性。我读过各种各样的书和关于它们的帖子,但我就是不明白

因为我不理解它们,我也不知道如何有效地使用它们

1) 你能给我一个关于属性是什么以及它的用途的好定义吗

2) 你能给我一个很好的C语言代码示例,说明如何创建和使用自定义属性吗?

有很多例子,例如。它们使用属性来引入AOP行为

这是我曾经使用过的一个属性,用来给属性一个单位(比如秒、米等)

它用于属性,如下所示:

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

您可以稍后检索属性以在GUI上显示它。

我可以给您一个示例,但与这篇优秀的文章相比,它显得有些苍白:

复杂的组件样式 企业期望的发展 现代软件开发人员的需求 更大的设计灵活性比 过去的设计方法。 微软的.NET框架使得 广泛使用属性来提供 通过以下方式添加功能: 被称为“声明式”编程。 属性增强了应用程序的灵活性 软件系统,因为它们促进 功能的松散耦合。 因为您可以创建自己的自定义 属性类,然后根据 他们,你可以利用松散的 您的应用程序的属性耦合能力 自己的目的


为完整起见,MSDN:



属性用于提供任何成员(字段、类等)的元数据

您可以通过继承来创建它们,并使用 方法

默认属性的一个示例是,它只允许经过身份验证的用户访问某些资源。例如:

[PrincipalPermission (SecurityAction.Demand, Role="Supervisor")]
public class DoTheThingPage : Page
{
    ////
}
在本例中,我们有一个ASP.NET页面,该页面只能由属于“主管”角色的经过身份验证的用户查看

(此属性由ASP.NET中的安全子系统自动读取)


还请注意,未使用类名的“属性”部分,这是.NET中的一种约定。

我们要求以特定的排序顺序在下拉列表中显示枚举值。我们使用自定义属性实现

[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
}

假设您有一个具有一系列属性的类,您将使用反射遍历这些属性。可能需要对任何字符串进行验证,以检查其长度是否不超过一定数量

然后,您可以创建一个
TextLength
属性,该属性具有默认的整数构造函数和整数属性/字段。然后可以读取类中每个字符串属性的属性,并将属性值的长度与属性中指定的数字进行比较

代码:


注意:未测试的属性只是向类、结构或某些成员添加附加信息(元数据)的一种方式。这些元数据可以由其他代码检索,以便做出一些决策

最简单的示例来自.NET。它表示该类稍后可以由BinaryFormatter序列化

下面是另一个示例
-我们可以在代码中用ImmutableAttribute标记一些类,以表明它们没有任何可变字段,并且可以进行多线程操作:

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

}
然后,我们可以创建一个单元测试,用于查找具有该属性的所有类,并确保:

[测试]
public void不可变\u类型\u应该\u不可变()
{
var=GlobalSetup.Types
其中(t=>t.Has());
foreach(装饰中的变量类型)
{
var count=type.GetAllFields().count(f=>!f.IsInitOnly&&!f.IsStatic);
AreEqual(0,count,“类型{0}应该是不可变的”,Type);
}
}
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");
               }
          }
     }
}
[Immutable]
public sealed class ProcessingMessage
{
    //... some code that should be thread-safe

}
[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);
  }
}