C#属性与特性,方法,反射

本文介绍了在C#中如何检索自定义属性的各种方法,包括检索单个实例、多个实例等,并提供了详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C# code

    public class Student
    {
        [CountAttribute("Id", "自动编号", 0)]
        public String StuName { get; set; }
        [CountAttribute("Id", "年龄", 0)]
        public Int32 Age { get; set; }
    }

            Student tempStu = new Student() { StuName = "Hello World", Age = 20 };
            var tempPIArray = tempStu.GetType().GetProperties();
            foreach (var tempPi in tempPIArray)
            {
                var tempAttributeArray = tempPi.GetCustomAttributes(typeof(CountAttribute), false);
                if (tempAttributeArray != null)
                {
                    foreach (var tempAttribute in tempAttributeArray as CountAttribute[])
                    {
                        if (tempAttribute.Counttype == "自动编号")
                        {
                            Console.WriteLine("It's me!");
                        }
                    }
                }
            }

 

 

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 方法将新属性初始化为要检索的属性值。初始化新属性后,只需使用其属性获取值即可。

Note要点

本主题描述如何检索已加载到执行上下文中的代码的属性。若要检索已加载到只反射上下文中的代码的属性,必须使用 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 方法将通知用户未找到任何属性,并显示不包含该属性的方法或类的名称。如果找到了属性,则控制台将显示 NameLevel 和 Reviewed 字段。

可使用 Type 类的成员获取已传递的类中的各个方法和成员。该示例首先查询 Type 对象以获取类级别的属性信息。然后使用 Type.GetMethods 将所有方法的实例放到 System.Reflection.MemberInfo 对象的一个数组中以检索方法级别的属性信息。还可使用 Type.GetProperties 方法检查属性级别上的属性,或使用 Type.GetConstructors 方法检查构造函数级别上的属性。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值