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