反射与属性

转载 2007年09月22日 00:47:00
反射是编程的读取与类型相关联的元数据的行为,通过元数据,你能了解它是什么类型以及它是由什么构成的(方法、属性、基类).
反射服务在system.Reflection命名空间中定义,它在和属性一起使用时最有用。
属性是一种向类型添加信息并影响类型行为的方法。
反射还允许在运行期间定义新类型,并生成相应的IL代码和元数据(使用在System.Reflection.Emit命名空间中的各种服务。
 
System.Type
基类Object定义了GetType()方法,使得你能对任何.NET对象调用这个方法
public class MyClass
{ ... }
 
int number = 0;
MyClass obj = new MyClass();
 
Type type1 = number.GetType();
Type type2 = number.GetType();
 
typeof运算符允许你直接检索与一个类型相关联的Type值,而无需实例化该类型的一个对象
Type type1 = typeof(int);
Type type2 = typeof(MyClass);
 
Type使你可以获取类型的元数据
 
Type type = typeof(MyClass);
string name = type.ToString();
Debug.Assert(name == “MyClass”);
 
示例:使用Type.GetMethods()来反射一个类型的公共方法
using System.Reflection;
 
public class MyClass
{
       public MyClass()
       {}
       public void Method1()
       {}
       public static void Method2()
       {}
       protected void Method3()
       {}
       protected void Method4()
       {}
}
 
//客户端代码
Type type = typeof(MyClass);
 
MethodInfo[] methodInfoArray = type.GetMethods();
 
//跟踪所有的公共方法
foreach (MethodInfo methodInfo in methodInfoArray)
{
       Trace.WriteLine(methodInfo.Name);
}
 
//输出
GetHashCode
Equals
ToString
Method1
Method2
GetType
 
GetMethods()的另一个版本,接受一个参数,告知如何绑定到该类型:
public abstract MethodInfo[] GetMethods(BindingFlags bindingAttr);
 
BindingFlags枚举,指定:实例方法、静态方法、非公共方法等
 
取得方法的MethodInfo对象,就可以调用它,即使该方法是受保护的或是私有的:
public object Invoke(object obj, object[] parameters);
晚绑定调用
 
示例:使用反射调用对象的私有方法
using System.Reflection;
 
public class MyClass
{
       public MyClass()
       { ... }
       public void Method1()
       { ... }
      
       public void Method2()
       { ... }
 
       public static void Method5()
       { ... }
 
       protected void Method3()
       { ... }
 
       private void Method4()
       { ... }
}
 
//客户端代码
MyClass obj =- new MyClass();
Type type = typeof(MyClass);
 
MethodInfo[] methodInfoArray;
methodInfoArray = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);
 
//仅调用私有方法
foreach (MethodInfo methodInfo in methodInfoArray)
{
       if (methodInfo.IsPrivate)
       {
              methodInfo.Invoke(obj, null);
}
}
 
GetMethod() ----------- MethodInfo
GetConstructors()、 GetConstructor() ------------------ ConstructorInfo
GetMember()、GetMembers()
GetEvent()、GetEvents()
 
属性
想法:可以用属性来修饰对象,而不需要通过编程实现各种功能和特性
 
属性本身是一个类,应该在名称中包含Attribute后缀,而且它必须派生于Attribute类:
 
public class FlagsAttribute : Attribute
{ ... }
 
如果属性名称是以Attribute结尾的,编译器允许省略Attribute后缀
[Flags]
public enum Color
{
       Red, Green, Blue, Purple = Red | Blue
}
 
每一个属性都有一个与它相关的AttributeUsage类型的属性,它指明了该属性应该用于哪种类型(类、接口、枚举等),哪种语法元素(构造函数、方法、参数、返回值等)。
AttributeUsage也指定同一属性是否能在目标上使用多次
 
属性能够有一个默认的构造函数,并可以接受多个构造参数。如果有一个默认构造函数,可以使用带括号的属性,也可使用不带括号的属性。
[MyAttribute()]
 
属性种类
.NET有三种属性。
标准属性:标准属性是.NET自带的,.NET编译器和运行时知道这些属性并遵照它们的指示。
自定义属性:自己提供的属性,除非编译器添加它们作为元数据的一部分,否则它们完全会被.NET忽略,你必须编写反射代码来使用自定义属性。这些属性经常包含具体问题域的定义
自定义上下文属性:你和.NET都可以提供自定义上下文属性。.NET完全注意到它们,会遵从它们的指令并相应地影响修饰对象
 
实现自定义属性
示例:实现一个自定义属性
public enum ColorOption { Red, Green, Blue }
 
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Interface)]
public class ColorAttribute : Attribute
{
       ColorOption m_Color;
       public ColorOption Color
       {
              get
              {
                     return m_Color;
              }
              set
              {
                     m_Color = value;
              }
       }
 
       public ColorAttribute()
{
       Color = ColorOption.Red;
}
public ColorAttribute(ColorOption color)
{
       this.Color = color;
}
}
 
使用ColorAttribute自定义属性的例子:
使用默认构造函数
[Color]
public class MyClass1 {}
使用参数化构造函数
[Color(ColorOption.Green)]
public class MyClass2 {}
使用属性
[Color(Color=ColorOption.Blue)]
public class MyClass3 {}
在接口上使用
[Color]
public interface IMyInterface {}
 
AttributeUsageAttribute的定义:
public sealed class AttributeUsageAttribute : Attribute
{
       public AttributeUsageAttribute(AttributeTargets validOn);
       public bool AllowMultiple { get; set; }
       /* 其他成员 */
}
 
AttributeTargets枚举,指出这种属性可以在哪些类型上使用
另一个属性是AllowMultiple, 默认情况下,AllowMultiple的设置为false,你只能为每个类或接口使用一次属性,如果明确地设置AllowMultiple为true,你就能为同一个目标多次使用同一属性
 
反射自定义属性
示例:反射自定义属性
public static ColorOption GetColor(object obj)
{
       Type objType = obj.GetType();
       Debug.Assert(objType.IsClass || objType.IsInterface);
 
       Type attribute = typeof(ColorAttribute);
 
       object[] attributeArray = objType.GetCustomAttributes(attribType, true);
 
       //最多只有一个color属性
       Debug.Assert(attributeArray.Length == 0 || attributeArray.Length == 1);
 
       if (attributeArray.Length == 0)
       {
              return ColorOption.Red;
}
 
ColorAttribute colorAttribute = (ColorAttribute)attributeArray[0];
return colorAttribute.Color;
}
 

反射访问属性,属性类型和修饰符

package xxx; import java.lang.reflect.Field; public class TestRef03 {     public static void...
  • msyqmsyq
  • msyqmsyq
  • 2016年06月02日 14:38
  • 1305

Java 反射(属性) 相当暴力啊 暴力反射

数据bean: package com.mth.bean; public class Person { private String name; private int age; publi...
  • m75100313
  • m75100313
  • 2014年01月06日 22:20
  • 1400

反射--Field

通过反射可以获得属性Field。 1、定义一个实体类package cn.com.refelct; public class Emp { private int no; private int...
  • yyywyr
  • yyywyr
  • 2013年11月17日 10:54
  • 2720

XML反射解析

和同事对接一个接口,采用xml传输,从root节点到叶节点总共套了13层,导致对应实体类的编写困难,同时在xml操作6层后反序列化的时候总是会丢失部分信息,于是便想有没有什么办法更加简单地解析xml,...
  • huang461072830
  • huang461072830
  • 2016年06月03日 14:14
  • 913

c# 如何通过反射 获取\设置属性值

http://www.cnblogs.com/Sandheart/archive/2013/04/03/2998181.html //定义类 public class MyClass { publ...
  • zunguitiancheng
  • zunguitiancheng
  • 2016年03月25日 11:02
  • 1204

iOS反射机制--1.属性反射

iOS属性反射:说白了,就是将两个对象的所有属性,用动态的方式取出来,并根据属性名,自动绑值。(注意:对象的类,如果是派生类,就得靠其他方式来实现了,因为得到不该基类的属性。) 本人常用的反射方式,...
  • zixiweimi
  • zixiweimi
  • 2015年01月20日 09:54
  • 917

C# 反射属性值和遍历属性名

using UnityEngine; using System.Collections; using System; using System.Reflection; public class Te...
  • qq617119142
  • qq617119142
  • 2015年02月27日 18:27
  • 1150

Java反射得到属性的值和设置属性的值

package com.whbs.bean; public class UserBean { private Integer id; private int age; ...
  • restraint
  • restraint
  • 2014年01月07日 08:41
  • 98970

java 通过反射获得类的属性和调用方法

public class TestClassA extends TestFather {  ... } public class TestFather {  private TestOther...
  • indieinside
  • indieinside
  • 2015年08月21日 10:41
  • 708

反射JS对象信息,属性值、方法一目了然。

var obj = 对象; var temp; for (var parm in obj) { temp += parm + "----" + obj[parm] + ""; } v...
  • Kujiu
  • Kujiu
  • 2010年08月05日 17:41
  • 1083
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:反射与属性
举报原因:
原因补充:

(最多只允许输入30个字)