2009-06-10 68 views
9

我不太了解属性。我已阅读过各种书籍&,但我只是不明白。在dotnet/.NET中实现自定义属性的最佳方式是什么?

由于我不理解他们,我也不明白如何有效地使用它们。

1)你能给我一个很好的定义什么是属性&它用于什么?

2)你可以给我一个很好的代码示例在C#中如何制作和使用自定义属性?

回答

9

假设您已经有了一系列具有一系列属性的类,您将使用反射来完成这些属性。任何字符串都可能需要验证,以检查它们是否不超过一定数量。

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

代码:

public class TextLengthAttribute : Attribute 
{ 
    private int length; 
    public int Length { get { retrun 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"); 
       } 
      } 
    } 
} 

注:未经检验

2

有很多在例如log4PostSharp。他们使用属性来引入AOP行为。

这是一个属性,我用了一次,给性质的单位(如秒,米,...)

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

    public Unit Unit { get; private set; } 
} 

它用在一些特性,如:

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

你以后可以检索该属性以在GUI上显示它。

11

我可以给你一个例子,但它会与此相比美好的文章苍白:

Defining and Using Custom Attribute Classes in C#

复杂,组件式 发展,企业的现代软件开发商预计出 要求 比过去的设计方法具有更大的设计灵活性。 微软的.NET框架使 广泛使用属性,通过 被称为“声明性”编程提供 增加的功能。 属性增强了软件系统的灵活性,因为它们促进了功能的松散耦合。 由于您可以创建自己的自定义 属性类别,然后根据 对它们进行操作,因此可以利用属性的耦合功能来实现自己的目的。

2

的属性被用来提供关于任何成员(字段,类等)的元数据。

您可以通过继承Attribute来创建它们,并通过使用 Attribute.GetCustomAttribute 方法来消耗它们。

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

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

在此示例中,我们有一个ASP.NET页面,只能由属于“Supervisor”角色的已验证用户查看。

(此属性自动ASP.NET中的安全子系统读取)另外请注意,未使用的类名的“属性”部分,它是.NET中的约定。

3

我们必须在一个下拉在特定的排序顺序显示枚举值的要求。我们使用自定义属性来实现。

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

属性只是添加附加信息(元数据)到类,结构或某些成员的方式。这个元数据可以被其他代码检索以作出一些决定。

最简单的示例是来自.NET的SerializableAttribute。它表明该类可以在稍后被BinaryFormatter序列化。

这里的另一个例子 - 我们可能标志着我们与ImmutableAttribute代码的一些类来表示他们没有任何可变域,并确定了多线程操作:

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

} 

然后,我们可以创建一个单元测试,查找具有该属性的所有类,并确保该属性可以确保: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); 
    } 
} 
相关问题