我有以下自定义属性,可以应用于属性:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class IdentifierAttribute : Attribute
{
}
例如:
public class MyClass
{
[Identifier()]
public string Name { get; set; }
public int SomeNumber { get; set; }
public string SomeOtherProperty { get; set; }
}
还有其他类,可以将Identifier属性添加到不同类型的属性中:
public class MyOtherClass
{
public string Name { get; set; }
[Identifier()]
public int SomeNumber { get; set; }
public string SomeOtherProperty { get; set; }
}
然后,我需要能够在我的消费类中获取此信息。 例如:
public class TestClass<T>
{
public void GetIDForPassedInObject(T obj)
{
var type = obj.GetType();
//type.GetCustomAttributes(true)???
}
}
最好的解决方法是什么? 我需要得到[Identifier()]字段的类型(int,string等)和实际值,显然是基于类型。
答案 0 :(得分:36)
如下所示,这将只使用它遇到的具有属性的第一个属性,当然你可以把它放在多个...
public object GetIDForPassedInObject(T obj)
{
var prop = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
.FirstOrDefault(p => p.GetCustomAttributes(typeof(IdentifierAttribute), false).Count() ==1);
object ret = prop !=null ? prop.GetValue(obj, null) : null;
return ret;
}
答案 1 :(得分:2)
public class TestClass<T>
{
public void GetIDForPassedInObject(T obj)
{
PropertyInfo[] properties =
obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
PropertyInfo IdProperty = (from PropertyInfo property in properties
where property.GetCustomAttributes(typeof(Identifier), true).Length > 0
select property).First();
if(null == IdProperty)
throw new ArgumentException("obj does not have Identifier.");
Object propValue = IdProperty.GetValue(entity, null)
}
}
答案 2 :(得分:2)
有点晚了,但这是我为枚举做的事情(也可能是任何对象)并使用扩展获取描述属性值(这可能是任何属性的通用):
public enum TransactionTypeEnum
{
[Description("Text here!")]
DROP = 1,
[Description("More text here!")]
PICKUP = 2,
...
}
获得价值:
var code = TransactionTypeEnum.DROP.ToCode();
支持我所有枚举的扩展程序:
public static string ToCode(this TransactionTypeEnum val)
{
return GetCode(val);
}
public static string ToCode(this DockStatusEnum val)
{
return GetCode(val);
}
public static string ToCode(this TrailerStatusEnum val)
{
return GetCode(val);
}
public static string ToCode(this DockTrailerStatusEnum val)
{
return GetCode(val);
}
public static string ToCode(this EncodingType val)
{
return GetCode(val);
}
private static string GetCode(object val)
{
var attributes = (DescriptionAttribute[])val.GetType().GetField(val.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : string.Empty;
}
答案 3 :(得分:-1)
这是一个更真实的例子。我们使用扩展方法,并检查属性是否包含FieldMetaDataAttribute(我的源代码库中的自定义属性) 有效的Major和MinorVersion。在这种特殊情况下,通常需要使用父类类型和GetProperties并检索ProperyInfo,然后使用GetCustomAttribute来检索属性FieldMetaDataAttribute的部分是普遍感兴趣的。使用此代码来启发您如何执行更通用的检索自定义属性的方法。当然可以完善此方法,以使其成为检索类实例任何属性的给定属性的通用方法。
/// <summary>
/// Executes the action if not the field is deprecated
/// </summary>
/// <typeparam name="TProperty"></typeparam>
/// <typeparam name="TForm"></typeparam>
/// <param name="form"></param>
/// <param name="memberExpression"></param>
/// <param name="actionToPerform"></param>
/// <returns>True if the action was performed</returns>
public static bool ExecuteActionIfNotDeprecated<TForm, TProperty>(this TForm form, Expression<Func<TForm, TProperty>> memberExpression, Action actionToPerform)
{
var memberExpressionConverted = memberExpression.Body as MemberExpression;
if (memberExpressionConverted == null)
return false;
string memberName = memberExpressionConverted.Member.Name;
PropertyInfo matchingProperty = typeof(TForm).GetProperties(BindingFlags.Public | BindingFlags.Instance)
.FirstOrDefault(p => p.Name == memberName);
if (matchingProperty == null)
return false; //should not occur
var fieldMeta = matchingProperty.GetCustomAttribute(typeof(FieldMetadataAttribute), true) as FieldMetadataAttribute;
if (fieldMeta == null)
{
actionToPerform();
return true;
}
var formConverted = form as FormDataContract;
if (formConverted == null)
return false;
if (fieldMeta.DeprecatedFromMajorVersion > 0 && formConverted.MajorVersion > fieldMeta.DeprecatedFromMajorVersion)
{
//major version of formConverted is deprecated for this field - do not execute action
return false;
}
if (fieldMeta.DeprecatedFromMinorVersion > 0 && fieldMeta.DeprecatedFromMajorVersion > 0
&& formConverted.MinorVersion >= fieldMeta.DeprecatedFromMinorVersion
&& formConverted.MajorVersion >= fieldMeta.DeprecatedFromMajorVersion)
return false; //the field is expired - do not invoke action
actionToPerform();
return true;
}