|
|
Type t = typeof(Program); foreach (PropertyInfo p in t.GetProperties()) { object[] o = p.GetCustomAttributes(true); }
/// <summary>
/// 对象属性克隆
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
public static object CloneObject(object o)
{
Type t =o.GetType();
PropertyInfo[] properties =t.GetProperties();
object p =t.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, null, o, null);
foreach ( PropertyInfo pi in properties )
{
if ( pi.CanWrite )
{
object value=pi.GetValue(o, null);
pi.SetValue(p, value, null);
}
}
return p;
}
检索自定义属性的过程很简单。首先,声明要检索的属性实例。然后,使用 Attribute.GetCustomAttribute 方法将新属性初始化为要检索的属性值。初始化新属性后,只需使用其属性获取值即可。
![]() |
---|
本主题描述如何检索已加载到执行上下文中的代码的属性。若要检索已加载到只反射上下文中的代码的属性,必须使用 CustomAttributeData 类,如如何:将程序集加载到仅反射上下文中所示。 |
本节描述下列检索属性的方法:
-
检索属性的一个实例
-
检索应用到同一范围的属性的多个实例
-
检索应用到不同范围的属性的多个实例
检索属性的一个实例
在下面的示例中,DeveloperAttribute(详见前一节的介绍)应用到类级别上的 MainApp 类。GetAttribute 方法使用 GetCustomAttribute 检索存储在类级别上 DeveloperAttribute 中的值,然后将这些值显示到控制台。
using System; [Developer( " Joan Smith " , " 42 " , Reviewed = true )] class MainApp { public static void Main() { // Call function to get and display the attribute. GetAttribute( typeof (MainApp)); } public static void GetAttribute(Type t) { // Get instance of the attribute. DeveloperAttribute MyAttribute = (DeveloperAttribute) Attribute.GetCustomAttribute( t, typeof (DeveloperAttribute)); if ( null == MyAttribute) { Console.WriteLine( " The attribute was not found. " ); } else { // Get the Name value. Console.WriteLine( " The Name Attribute is: {0}. " , MyAttribute.Name); // Get the Level value. Console.WriteLine( " The Level Attribute is: {0}. " , MyAttribute.Level); // Get the Reviewed value. Console.WriteLine( " The Reviewed Attribute is: {0}. " , MyAttribute.Reviewed); } } }
该程序在执行时显示下列文本。
The Name Attribute is: Joan Smith.
The Level Attribute is: 42.
The Reviewed Attribute is: True.
如果未找到该属性,则 GetCustomAttribute 方法将 MyAttribute 初始化为一个空值。该示例检查 MyAttribute 以查找这样的实例,如未找到任何属性,则通知用户。如果在类范围中未找到 DeveloperAttribute,则下列消息将显示到控制台。
The attribute was not found.
该示例假定属性定义位于当前命名空间中。如果属性定义不在当前命名空间中,请务必导入该属性定义所驻留的命名空间。
检索应用到同一范围的属性的多个实例
在前一个示例中,要检查的类和要查找的特定属性被传递到 GetCustomAttribute。如果类级别上只应用属性的一个实例,则该代码将运行良好。但是,如果在同一类级别上应用属性的多个实例,则 GetCustomAttribute 方法不检索所有信息。如果同一个属性的多个实例应用到相同的范围,可使用 Attribute.GetCustomAttributes 将属性的所有实例放到一个数组中。例如,如果在同一个类的类级别上应用 DeveloperAttribute 的两个实例,则可修改 GetAttribute 方法以显示同时存在于这两个属性中的信息。请记住,要在同一级别上应用多个属性,必须在定义该属性时在 AttributeUsageAttribute 中将 AllowMultiple 属性设置为 true。
下面的代码示例说明如何使用 GetCustomAttributes 方法创建在任意给定类中引用 DeveloperAttribute 的所有实例的数组。然后,所有属性的值将显示到控制台。
public static void GetAttribute(Type t) { DeveloperAttribute[] MyAttribute = (DeveloperAttribute[]) Attribute.GetCustomAttributes( t, typeof (DeveloperAttribute)); if(null == MyAttribute) { Console.WriteLine("The attribute was not found."); } else { for(int i = 0 ; i < MyAttribute.Length ; i++) { //Get the Name value. Console.WriteLine("The Name Attribute is: {0}." , MyAttribute[i].Name); //Get the Level value. Console.WriteLine("The Level Attribute is: {0}." , MyAttribute[i].Level); //Get the Reviewed value. Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute[i].Reviewed); } } }
如果没有找到任何属性,该代码将提醒用户。否则,将显示两个 DeveloperAttribute 实例中都包含的信息。
检索应用到不同范围的属性的多个实例
GetCustomAttributes 方法和 GetCustomAttribute 方法不搜索整个类和返回该类中某个属性的所有实例。相反,它们一次只搜索一个指定方法或成员。如果将具有同一属性的某个类应用到每个成员,并要检索应用到这些成员的所有属性值,则必须向 GetCustomAttributes 和 GetCustomAttribute 分别提供每个方法或成员。
下面的代码示例将类用作参数,并在类级别上以及该类的每个方法上搜索 DeveloperAttribute(先前已定义)。
public static void GetAttribute(Type t) { DeveloperAttribute att; // Get the class-level attributes. // Put the instance of the attribute on the class level in the att object. att = (DeveloperAttribute) Attribute.GetCustomAttribute ( t, typeof (DeveloperAttribute)); if ( null == att) { Console.WriteLine( " No attribute in class {0}./n " , t.ToString()); } else { Console.WriteLine( " The Name Attribute on the class level is: {0}. " , att.Name); Console.WriteLine( " The Level Attribute on the class level is: {0}. " , att.Level); Console.WriteLine( " The Reviewed Attribute on the class level is: {0}./n " , att.Reviewed); } // Get the method-level attributes. // Get all methods in this class, and put them // in an array of System.Reflection.MemberInfo objects. MemberInfo[] MyMemberInfo = t.GetMethods(); // Loop through all methods in this class that are in the // MyMemberInfo array. for ( int i = 0 ; i < MyMemberInfo.Length; i ++ ) { att = (DeveloperAttribute) Attribute.GetCustomAttribute( MyMemberInfo[i], typeof (DeveloperAttribute)); if ( null == att) { Console.WriteLine( " No attribute in member function {0}./n " , MyMemberInfo[i].ToString()); } else { Console.WriteLine( " The Name Attribute for the {0} member is: {1}. " , MyMemberInfo[i].ToString(), att.Name); Console.WriteLine( " The Level Attribute for the {0} member is: {1}. " , MyMemberInfo[i].ToString(), att.Level); Console.WriteLine( " The Reviewed Attribute for the {0} member is: {1}./n " , MyMemberInfo[i].ToString(), att.Reviewed); } } }
如果在方法级别或类级别上未找到 DeveloperAttribute 的任何实例,GetAttribute 方法将通知用户未找到任何属性,并显示不包含该属性的方法或类的名称。如果找到了属性,则控制台将显示 Name、Level 和 Reviewed 字段。
可使用 Type 类的成员获取已传递的类中的各个方法和成员。该示例首先查询 Type 对象以获取类级别的属性信息。然后使用 Type.GetMethods 将所有方法的实例放到 System.Reflection.MemberInfo 对象的一个数组中以检索方法级别的属性信息。还可使用 Type.GetProperties 方法检查属性级别上的属性,或使用 Type.GetConstructors 方法检查构造函数级别上的属性。