在.net框架體系內,反射特性較多的應用到。反射的相關定義分為兩種。
自然解釋:射是一種自然現象,表現為受刺激物對刺激物的逆反應;這是反射的字面解釋,我們看一下計算機編程中的反射;
編程解釋:通過 System.Reflection 命名空間中的類以及 System.Type,您可以獲取有關已加載的程序集和在其中定義的類型(如類、接口和值類型)的信息。 您也可以使用反射在運行時創建類型實例,以及調用和訪問這些實。
反射(Reflection)有下列用途:它允許在運行時查看屬性(attribute)信息;它允許審查集合中的各種類型,以及實例化這些類型;它允許延遲綁定的方法和屬性(property);它允許在運行時創建新類型,然後使用這些類型執行一些任務。
下面介紹一下有關反射的程序集的相關屬性和方法的源碼:
(1).Object的GetType()方法:
// Returns a Type object which represent this object instance.
//
[System.Security.SecuritySafeCritical] // auto-generated
[Pure]
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Type GetType();
(2).PropertyInfo的GetProperty()方法:
public PropertyInfo GetProperty(String name,BindingFlags bindingAttr,Binder binder,
Type returnType, Type[] types, ParameterModifier[] modifiers)
{
if (name == null)
throw new ArgumentNullException("name");
if (types == null)
throw new ArgumentNullException("types");
Contract.EndContractBlock();
return GetPropertyImpl(name,bindingAttr,binder,returnType,types,modifiers);
}
public PropertyInfo GetProperty(String name, Type returnType, Type[] types,ParameterModifier[] modifiers)
{
if (name == null)
throw new ArgumentNullException("name");
if (types == null)
throw new ArgumentNullException("types");
Contract.EndContractBlock();
return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,modifiers);
}
public PropertyInfo GetProperty(String name, BindingFlags bindingAttr)
{
if (name == null)
throw new ArgumentNullException("name");
Contract.EndContractBlock();
return GetPropertyImpl(name,bindingAttr,null,null,null,null);
}
public PropertyInfo GetProperty(String name, Type returnType, Type[] types)
{
if (name == null)
throw new ArgumentNullException("name");
if (types == null)
throw new ArgumentNullException("types");
Contract.EndContractBlock();
return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,null);
}
public PropertyInfo GetProperty(String name, Type[] types)
{
if (name == null)
throw new ArgumentNullException("name");
if (types == null)
throw new ArgumentNullException("types");
Contract.EndContractBlock();
return GetPropertyImpl(name,Type.DefaultLookup,null,null,types,null);
}
public PropertyInfo GetProperty(String name, Type returnType)
{
if (name == null)
throw new ArgumentNullException("name");
if (returnType == null)
throw new ArgumentNullException("returnType");
Contract.EndContractBlock();
return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,null,null);
}
internal PropertyInfo GetProperty(String name, BindingFlags bindingAttr, Type returnType)
{
if (name == null)
throw new ArgumentNullException("name");
if (returnType == null)
throw new ArgumentNullException("returnType");
Contract.EndContractBlock();
return GetPropertyImpl(name, bindingAttr, null, returnType, null, null);
}
public PropertyInfo GetProperty(String name)
{
if (name == null)
throw new ArgumentNullException("name");
Contract.EndContractBlock();
return GetPropertyImpl(name,Type.DefaultLookup,null,null,null,null);
}
(3).Object的GetValue()方法:
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
public Object GetValue(Object obj)
{
return GetValue(obj, null);
}
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
public virtual Object GetValue(Object obj,Object[] index)
{
return GetValue(obj, BindingFlags.Default, null, index, null);
}
public abstract Object GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture);
以上介紹了一下有關反射的相關方法的底層方法源碼,現在介紹一下較為通用的方法:
(1).獲取對象的所有公共屬性。
/// <summary>
/// 獲取對象的所有公共屬性。
/// </summary>
/// <param name="obj">定義該方法的數據類型。</param>
/// <returns>返回包含該對象的屬性信息的數組。</returns>
public static IEnumerable<PropertyInfo> GetProperties(this object obj)
{
return obj.GetType().GetProperties();
}
(2).獲取一個對象的屬性。
/// <summary>
///獲取一個對象的屬性。
/// </summary>
/// <param name="obj">定義該方法的數據類型。gb</param>
/// <param name="flags">提供要確定要檢索的屬性的標志。</param>
/// <returns>返回包含該對象的屬性信息的數組。</returns>
public static IEnumerable<PropertyInfo> GetProperties(this object obj, BindingFlags flags)
{
return obj.GetType().GetProperties(flags);
}
(3).用指定名稱獲取具有指定名稱的屬性的當前對象的屬性值。
/// <summary>
///用指定名稱獲取具有指定名稱的屬性的當前對象的屬性值。
/// </summary>
/// <param name="obj">要檢索的屬性值的對象。</param>
/// <param name="propertyName">要檢索的屬性的名稱。</param>
/// <returns>返回屬性的值。</returns>
public static object GetPropertyValue(this object obj, string propertyName)
{
var item = obj.GetType().GetProperty(propertyName);
if (item == null) return null;
var value = obj.GetType().GetProperty(propertyName).GetValue(obj);
if (item.PropertyType.IsGenericType)
{
value = item.PropertyType.GetProperty(propertyName);
}
return value;
}
(4).獲取一個枚舉字符串值。
/// <summary>
///獲取一個枚舉字符串值。
/// </summary>
/// <param name="obj">該枚舉返回的字符串值。</param>
/// <returns>返回一個枚舉字符串值。</returns>
public static string GetStringValue(this System.Enum obj)
{
var fieldInfo = obj.GetType().GetField(obj.ToString());
var attributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
var output = (StringValueAttribute)attributes.GetValue(0);
return output.Text;
}
(5).獲取方法調用。
/// <summary>
/// 獲取方法調用
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="action"></param>
/// <returns></returns>
public static MethodCallExpression GetMethodCall<T>(Expression<T> action )
{
var call = action.Body as MethodCallExpression;
return call;
}
(6).獲取類型名稱.
/// <summary>
/// 獲取類型名稱
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static string GetTypeName<T>()
{
return typeof (T).Name;
}
(7).獲取參數值
/// <summary>
/// 獲取參數值
/// </summary>
/// <param name="methodCall"></param>
/// <returns></returns>
public static IEnumerable<Tuple<ParameterInfo, object>> GetArgumentValues(MethodCallExpression methodCall)
{
var parameters = methodCall.Method.GetParameters();
if (!parameters.Any()) yield break;
for(var i = 0; i < parameters.Length; i++)
{
var arg = methodCall.Arguments[i];
var ceValue = arg as ConstantExpression;
if (ceValue != null)
yield return new Tuple<ParameterInfo, object>(parameters[i], ceValue.Value);
else
yield return new Tuple<ParameterInfo, object>(parameters[i], GetExpressionValue(arg));
}
}
(8).獲取表達式值
/// <summary>
/// 獲取表達式值
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
private static object GetExpressionValue(Expression expression)
{
var lambda = Expression.Lambda<Func<object>>(Expression.Convert(expression, typeof (object)));
var func = lambda.Compile();
return func();
}
反射類的繼承層次如下:
System.reflection
System.Reflection.Assembly
System.Reflection.MemberInfo
System.Reflection.EventInfo
System.Reflection.FieldInfo
System.Reflection.MethodBase
System.Reflection.ConstructorInfo
System.Reflection.MethodInfo
System.Reflection.PropertyInfo
System.Type