.NET自定义属性的属性?
-
25-09-2019 - |
题
编辑: 我最好改一下: 如何可以我一开始实施一个类属性的/转移到使用自定义属性吗(我增加instantation瓦尔(类名,PROPERTYNAME)的属性,但是我宁愿有这些自动获取ofcourse。)
Public Class CustomClass
<CustomAttributeClass(ClassName:="CustomClass", PropertyName = "SomeProperty")> _
Public Property SomeProperty() as String
Get() as String
//This implementation should be handled by the attribute class
End Get
Set(Byval value as String)
Me._someProperty = value
End Set
End Property
End Class
老问题:
我想创建一个类的自定义属性特性。我可以创建一个从属性派生的类,和“标记”具有属性的属性,但在哪里何去何从?
我有一个仓库,我可以很快得到一个基于属性值数据。我想概括属性中的属性的行为,但我不知道如何从这里走...任何帮助会接受!
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
解决方案
您将不得不使用反射来发现的属性。在你的情况,你会从PropertyInfo.GetCustomAttributes()得到它。
使用属性的较硬部分是找到实际使用它们合适的执行模型。就像一个编译器,一个设计师或对象序列化一类的东西是一个明显的例子。属性的可用性迅速从那里盘旋下降。它几乎总是错误的选择,当您尝试使用地方实际需要虚拟财产的属性。检索属性值的幅度高于检索属性值更昂贵的价格昂贵,很多订单。使用它们仅当反射代码运行在人类的时间(如编译器),或者当相比(在任何类型的I / O操作共同)下的权益或开销的成本是微不足道的。
其他提示
从您的意见以前的答案,我想你会发现,你希望他们是.NET属性不是很灵活。
您问:“是不是有一些基本的财产属性,它有一个像使用onGET和发病的一些事件?” - 无;属性没有内置与其靶相互作用,无论是方法或类。事实上,你甚至不能在运行时告诉属性的目标是什么;你必须首先,然后查询其属性装饰它知道目标(类,方法,属性等)。
其次,实际上并没有创建的属性,直到您查询他们。当你调用GetCustomAttributes
,运行时系统评估的程序集元数据和实例中指定的属性。如果连续两次调用它,你会得到两套相同的属性。
让我们再回到您的其他问题:如果你想在装饰着你的属性的属性设置或检索要知道,你必须实现对所有相关的类INotifyPropertyChanged
,写代码来搜索所有类的属性标有在装配载荷属性,然后建立一些交互性迷上了PropertyChanged
事件需要火任何代码。 (这仅通知您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);
}
}