简体   繁体   English

如何在.NET 2.0中实现自定义属性?

[英]How can I implement custom attributes in .NET 2.0?

Unfortunately I am still working on .NET 2.0. 不幸的是,我仍在开发.NET 2.0。 I have not created a custom attribute before. 我之前没有创建自定义属性。 I want to create a CustomStringFormatAttribute :. 我想创建一个CustomStringFormatAttribute

If a class, say Customer.Name, has: 如果一个类,例如Customer.Name,具有:

MaxLength=30
ActualLength=10

I need to pad it with empty spaces till it reached 30. 我需要用空白填充它,直到达到30。

I also need an attribute for date that I can format like DisplayDataFormat 我还需要一个可以格式化的日期属性,例如DisplayDataFormat

I have created the following but How do I get access to the actual value of the property within the attribute? 我创建了以下内容,但如何访问属性内属性的实际值?

public class Customer
{
    [CustomStringFormatAttribute(30)]
    public string Name { get; set; }

    //todo:customDateAttribute
    public DateTime StartDate { get; set; }
}

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
public sealed class CustomStringFormatAttribute : Attribute
{
    private readonly int maxLength;

    public CustomStringFormatAttribute(int maxLength)
    {
       MaxLength = maxLength;
    }

    public  int MaxLength { get; private set; }

    //?Should I override ToString 
    public override string ToString()
    {
        return Format();
    }

    private string Format()
    {
        //simplified version of my formatting for brevity
        string source = "value from the property of the class.";//How do I get access to the actual value of the property within the attribute?
        const char paddingChar = ' ';
        return source.PadLeft(maxLength, paddingChar);
    }    
}

Any suggestions? 有什么建议么?

Note: I' used automatic property for brevity. 注意:为简洁起见,我使用了自动属性。 I don't have that luxury in .NET 2.0. 在.NET 2.0中,我没有那么奢侈的东西。

Sorry, you cannot access the class instance or the property info inside your attribute. 抱歉,您无法访问类实例或属性内的属性信息。 You should write an additional method, for example a static method in some "static" class, that allow you to do what you want to do. 您应该编写其他方法,例如在某些“静态”类中的静态方法,该方法允许您执行想要执行的操作。

Example.... 例....

    public static string FormatProperty(object instance, PropertyInfo property)
    {
        CustomStringFormatAttribute attrib = Attribute.GetCustomAttribute(property, typeof(CustomStringFormatAttribute)) as CustomStringFormatAttribute;
        return property.GetValue(instance, null).ToString().PadLeft(attrib.MaxLength, ' ');
    }

    public static string FormatProperty(object instance, string propertyName)
    {
        return FormatProperty(instance, instance.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance));
    }

But this is very uncomfortable and insanely slow since uses reflection to get property value through property info. 但这是非常不舒服的,而且非常缓慢,因为使用反射通过属性信息获取属性值。

To access property attributes you need a PropertyInfo. 要访问属性,您需要一个PropertyInfo。

    public static int GetPropertyMaxLength(PropertyInfo property)
    {
        CustomStringFormatAttribute attrib = Attribute.GetCustomAttribute(property, typeof(CustomStringFormatAttribute)) as CustomStringFormatAttribute;
        return attrib != null ? attrib.MaxLength : int.MaxValue;
    }

    public static int GetPropertyMaxLength(Type type, string propertyName)
    {
        return GetPropertyMaxLength(type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance));
    }

Let's suppose we put these functions inside the attribute. 假设我们将这些函数放在属性中。 Then we want to override, for example, our ToString method in our class Customer. 然后,我们想覆盖例如Customer类中的ToString方法。

public override string ToString()
{
    return CustomStringFormatAttribute.FormatProperty(this, "Name");
}

The problem with this is of course Speed, it uses reflection by name, very slow, and Refactoring, you will not have a compile time warning or error if property "Name" doesn't exists, you will get only an exception at runtime. 当然,问题在于速度,它使用名称反射,非常慢的速度和重构,如果属性“ Name”不存在,则不会出现编译时警告或错误,在运行时您只会得到一个异常。 I would suggest you to use another mechanism. 我建议您使用其他机制。

With newer version of the language you could use lambda expressions to obtain your property info directly by the property itself, but since you are in C# 2.0 this is not possible. 使用较新版本的语言,您可以使用lambda表达式直接通过属性本身获取属性信息,但是由于您使用的是C#2.0,因此无法实现。

Another solution can be: add instead another property called FormattedXXX, for example FormattedName that returns the lenght as you want it and you can use that property instead of the Name property. 另一个解决方案可以是:添加另一个名为FormattedXXX的属性,例如FormattedName,它根据需要返回长度,并且您可以使用该属性代替Name属性。 This will allow you to keep your formatted version of the property near your property. 这将使您可以将属性的格式化版本保留在属性附近。

You need to do it the other way around. 您需要反过来做。 You shouldn't have any logic in your attribute, it should simply expose properties with the information it contains (eg a MaxLength property). 您的属性中不应包含任何逻辑,而应仅使用其包含的信息公开属性(例如MaxLength属性)。 Then your Customer class should access the information provided by CustomStringFormatAttribute and format it accordingly: 然后,您的Customer类应访问CustomStringFormatAttribute提供的信息,并相应地设置其格式:

private string m_Name;

public string Name
{
    get
    {
        var formatAttribute = typeof(Customer).GetCustomAttributes(false)
                                  .OfType<CustomStringFormatAttribute>
                                  .SingleOrDefault();

        if (formatAttribute != null)
            return m_Name.PadLeft(formatAttribute.MaxLength);

        return m_Name;
    }
    set
    {
        m_Name = value;
    }
}

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

相关问题 如何在.NET Standard 2.0项目上实现Dotfuscator? - How can I implement Dotfuscator on a .NET Standard 2.0 project? 如何将依赖项注入 asp.net core 2.0 中的自定义 ILogger? - How can I inject dependencies into a custom ILogger in asp.net core 2.0? 如何在ASP.NET MVC中使用自定义属性扩展Identity? - How can I extend Identity with custom attributes in ASP.NET MVC? 如何让用 ASP.Net Core 2.0 编写的自定义异常处理程序在 ASP.Net Core 3.1 中工作? - How can I get a custom exception handler written in ASP.Net Core 2.0 to work in ASP.Net Core 3.1? 如何在没有身份的asp.net MVC中实现自定义身份验证/授权? - How can I implement custom authentication/authorization in asp.net MVC without Identity? ext.net 2.0-获取树节点的自定义属性 - ext.net 2.0 - get custom attributes of a tree node 如何在.net 2.0项目中使用.net 3.0类? - How can I use .net 3.0 class in .net 2.0 project? 如何在.net core 2.0中实现HttpContext? - How to implement HttpContext in .net core 2.0? 如何遍历C#类(.NET 2.0)的属性? - How do I iterate through the Attributes of a C# class (.NET 2.0)? 在dotnet / .NET中实现自定义属性的最佳方法是什么? - What's the best way to implement custom attributes in dotnet/.NET?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM