.NET自定义属性?

.NET自定义属性?,.net,vb.net,attributes,custom-attributes,.net,Vb.net,Attributes,Custom Attributes,编辑: 我最好换个说法: 如何使用自定义属性将类属性的GET实现转换为/呢?(我已经在属性中添加了instantation变量(classname,propertyname),当然我更希望自动获取这些变量。) 公共类CustomClass _ 公共属性SomeProperty()作为字符串 Get()作为字符串 //这个实现应该由属性类处理 结束 设置(Byval值作为字符串) Me.\u someProperty=value 端集 端属性 末级 老问题: 我想为类创建一个自定义属性。我可以

编辑: 我最好换个说法: 如何使用自定义属性将类属性的GET实现转换为/呢?(我已经在属性中添加了instantation变量(classname,propertyname),当然我更希望自动获取这些变量。)

公共类CustomClass
_
公共属性SomeProperty()作为字符串
Get()作为字符串
//这个实现应该由属性类处理
结束
设置(Byval值作为字符串)
Me.\u someProperty=value
端集
端属性
末级

老问题:

我想为类创建一个自定义属性。我可以创建一个从属性派生的类,并用该属性“标记”属性,但是从这里开始该怎么做呢

我有一个存储库,可以根据属性值快速获取数据。我想概括属性中属性的行为,但我不知道如何从这里开始。。。任何帮助都会被极大地接受

Public Class CustomDataAttribute : Inherits Attribute
    Private _name As String

    Public Sub New(ByVal name As String)
        Me.Name = name
    End Sub

    Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            Me._name = value
        End Set
    End Property
End Class


Public Class CustomClass
    <CustomDataAttribute(Name:="CustomField")> _ 
    Public Property CustomField()
    End Property
End Class
公共类CustomDataAttribute:继承属性
Private\u名称作为字符串
Public Sub New(ByVal名称作为字符串)
Me.Name=Name
端接头
属性名()作为字符串
得到
返回\u名称
结束
设置(ByVal值作为字符串)
Me.\u name=值
端集
端属性
末级
公共类CustomClass
_ 
公共属性CustomField()
端属性
末级

您必须使用反射来发现属性。在本例中,您将从PropertyInfo.GetCustomAttributes()获得它


使用属性最困难的部分是找到一个合适的执行模型来实际使用它们。编译器、设计器或序列化对象的类是显而易见的。属性的可用性从那里迅速下降。当您试图使用实际需要虚拟财产的属性时,这几乎总是错误的选择。检索属性值非常昂贵,比检索属性值要贵很多数量级。仅当反射代码在人工时间运行时(如编译器)或成本与好处或开销相比微不足道时(在任何类型的I/O操作中都很常见)才使用它们。

从您对前面答案的评论中,我想您会发现.NET属性并不像您希望的那样灵活

您问“是否有一些基本属性属性包含一些事件,如onGet和start?”--否;属性与其目标(无论是方法还是类)没有内置交互。事实上,您甚至无法在运行时判断属性的目标是什么;您必须首先知道目标(类、方法、属性等),然后查询哪些属性修饰它

其次,在查询属性之前,不会实际创建属性。调用
GetCustomAttributes
时,运行时系统会评估程序集元数据并实例化指定的属性。如果连续调用两次,将得到两组相同的属性

回到您的另一个问题:如果您想知道何时设置或检索用属性修饰的属性,您必须在所有相关类上实现
INotifyPropertyChanged
,编写代码在程序集加载时搜索所有类中标记有该属性的属性,然后构建一些互动性,将
属性更改
事件连接到您需要触发的任何代码。(这只会通知您有关
set
操作的信息,而不是
get


不知道这是否有帮助,但这就是答案。:-)

这里有一个类,在使用反射时帮助处理自定义属性。将类型作为参数传递给构造函数

public class AttributeList : List<Attribute>
{
    /// <summary>
    /// Gets a list of custom attributes
    /// </summary>
    /// <param name="propertyInfo"></param>
    /// <returns></returns>
    public static AttributeList GetCustomAttributeList(ICustomAttributeProvider propertyInfo)
    {
        var result = new AttributeList();
        result.AddRange(propertyInfo.GetCustomAttributes(false).Cast<Attribute>());
        return result;
    }

    /// <summary>
    /// Finds attribute in collection by its own type or parents type
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T FindAttribute<T>() where T : Attribute
    {
        return (T)Find(x => typeof(T).IsAssignableFrom(x.GetType()));
    }

    /// <summary>
    /// Finds attribute in collection by its own type or parents type
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public List<T> FindAllAttributes<T>() where T : Attribute
    {
        return new List<T>(FindAll(x => typeof(T).IsAssignableFrom(x.GetType())).Cast<T>());
    }

    /// <summary>
    /// Finds attribute in collection by its own type or parents type
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public List<T> FindAllAttributes<T>(Type implementsType) where T : Attribute
    {
        return new List<T>(FindAll(x => implementsType.IsAssignableFrom(x.GetType())).Cast<T>());
    }

    public bool IsAttributeSet<T>() where T : Attribute
    {
        return FindAttribute<T>() != null;
    }

    public TValue GetValueFromAttributeOrDefault<TAttr, TValue>(Func<TAttr, TValue> func, TValue defaultValue) 
        where TAttr : Attribute
    {
        var attribute = FindAttribute<TAttr>();
        return attribute == null ? 
            defaultValue : 
            func(attribute);
    }
}
公共类属性列表:列表
{
/// 
///获取自定义属性的列表
/// 
/// 
/// 
公共静态属性列表GetCustomAttributeList(ICCustomAttributeProviderPropertyInfo)
{
var result=新属性列表();
AddRange(propertyInfo.GetCustomAttributes(false.Cast());
返回结果;
}
/// 
///按其自身类型或父类型在集合中查找属性
/// 
/// 
/// 
public T FindAttribute(),其中T:Attribute
{
返回(T)Find(x=>typeof(T).IsAssignableFrom(x.GetType());
}
/// 
///按其自身类型或父类型在集合中查找属性
/// 
/// 
/// 
公共列表FindAllAttributes(),其中T:Attribute
{
返回新列表(FindAll(x=>typeof(T).IsAssignableFrom(x.GetType()).Cast());
}
/// 
///按其自身类型或父类型在集合中查找属性
/// 
/// 
/// 
公共列表FindAllAttributes(类型implementsType),其中T:Attribute
{
返回新列表(FindAll(x=>implementsType.IsAssignableFrom(x.GetType()).Cast());
}
public bool IsAttributeSet(),其中T:Attribute
{
返回FindAttribute()!=null;
}
公共TValue从AttributeOrderFault获取值(Func Func,TValue defaultValue)
其中TAttr:Attribute
{
var属性=FindAttribute();
返回属性==null?
默认值:
func(属性);
}
}

从这里到哪里?你想去哪里?您想要实现什么?CustomClass是一个数据类,它将数据存储在与其关联的表中。我想覆盖几个属性并将它们存储在一个单独的表中(以及来自其他自定义类的其他属性,这些自定义类需要从它们自己的表中提取数据)。请详细说明:我想将本地化应用于自定义业务对象的属性。属性的重写/属性化是一种非常糟糕的方式吗?如果每个对象只有一个属性,我会创建
public class AttributeList : List<Attribute>
{
    /// <summary>
    /// Gets a list of custom attributes
    /// </summary>
    /// <param name="propertyInfo"></param>
    /// <returns></returns>
    public static AttributeList GetCustomAttributeList(ICustomAttributeProvider propertyInfo)
    {
        var result = new AttributeList();
        result.AddRange(propertyInfo.GetCustomAttributes(false).Cast<Attribute>());
        return result;
    }

    /// <summary>
    /// Finds attribute in collection by its own type or parents type
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T FindAttribute<T>() where T : Attribute
    {
        return (T)Find(x => typeof(T).IsAssignableFrom(x.GetType()));
    }

    /// <summary>
    /// Finds attribute in collection by its own type or parents type
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public List<T> FindAllAttributes<T>() where T : Attribute
    {
        return new List<T>(FindAll(x => typeof(T).IsAssignableFrom(x.GetType())).Cast<T>());
    }

    /// <summary>
    /// Finds attribute in collection by its own type or parents type
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public List<T> FindAllAttributes<T>(Type implementsType) where T : Attribute
    {
        return new List<T>(FindAll(x => implementsType.IsAssignableFrom(x.GetType())).Cast<T>());
    }

    public bool IsAttributeSet<T>() where T : Attribute
    {
        return FindAttribute<T>() != null;
    }

    public TValue GetValueFromAttributeOrDefault<TAttr, TValue>(Func<TAttr, TValue> func, TValue defaultValue) 
        where TAttr : Attribute
    {
        var attribute = FindAttribute<TAttr>();
        return attribute == null ? 
            defaultValue : 
            func(attribute);
    }
}