精通C#--类型反射,晚期绑定和基于特性的编程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/x13262608581/article/details/82050434

反射

1.
.NET中反射是一个运行库类型发现的过程。
使用反射服务,可通过编程使用一个友好的对象模型得到元数据信息。

2.
NameSpace: System.Reflection
Assembly
AssemblyName
EventInfo
FieldInfo
MemberInfo
MethodInfo
Module
ParameterInfo
PropertyInfo

System.Type

System.Object.GetType()//
typeof(ClassName)// typeof(MyClass)
Type.GetType()
// Type.GetType(“AssemblyName.ClassName [+ InsertedClassName], [AssemblyName]”, bool bThrowException_, bool bNotIdentifyCase);
// Type.GetType(“AssemblyName.泛型ClassName`参数个数 [+ InsertedClassName], [AssemblyName]”, bool bThrowException_, bool bNotIdentifyCase);

3.动态加载程序集
3.1.
Assembly.Load(Name(, Version=major.minor.build.revision) (, Culture=culture token) (, PublicKeyToken= public key token))

3.2.

AssemblyName asmName;
asmName = new AssemblyName();
asmName.Name = "CarLibrary";
Version v = Version("1.0.0.0");
asmName.Version = v;
Assembly a = Assembly.Load(asmName);

晚期绑定

创建一个给定类型的实例,并在运行时调用其成员。
不需要在编译时知道它存在。
1.
Object Activator.CreateInstance(Type type);

public class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("***Fun with Late Binding***");
        Assembly a = null;
        try
        {
            a = Assembly.Load("CarLibrary");
        }
        catch(FileNotFoundException ex)
        {
            Console.WriteLine(ex.Message);
            return;
        }

        if(a != null)
            CreateUsingLateBinding(a);

        Console.ReadLine();
    }

    static void CreateUsingLateBinding(Assembly asm)
    {
        try
        {
            Type miniVan = asm.GetType("CarLibrary.MiniVan");
            // 返回永远为object
            object obj = Activator.CreateInstance(miniVan);
            Console.WriteLine("Created a {0} using late binding!", obj);
            // 触发方法调用
            MethodInfo mi = miniVan.GetMethod("TurboBoost");
            // 触发类型中方法调用
            mi.Invoke(obj, null);
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

    static void InvokeMethodWithArgsUsingLateBinding(Assembly asm)
    {
        try
        {
            Type sport = asm.GetType("CarLibrary.SportsCar");
            object obj = Activator.CreateInstance(sport);
            MethodInfo mi = sport.GetMethod("TurnOnRadio");
            mi.Invoke(obj, new object[]{true, 2});
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

.NET特性

1..NET特性是扩展了抽象的System.Attribute基类的类类型。
2.预定义特性的几个例子
[CLSCompliant] 强制被注释项遵从CLS
[DllImport] 允许.NET代码调用任意非托管的C/C++基础类库。
[Obsolete] 标记一个不用的类或成员
[Serializable] 标记一个类或结构可被序列化
[NonSerialized] 指定类或结构中的某个字段不能在序列化过程中被持久化
[ServiceContract]

[Obsolete("Use another vehicle!")]
public class HorseAndBuggy
{
    ...
}

public sealed class ObsoleteAttribute : Attribute
{
    // 给特性提供构造参数时,直到参数被其它类型或外部工具反射后,特性才分配到内存。
    // 定义在特性级的字符串数据作为元数据介绍被存储在程序集。
    public ObsoleteAttribute(string message, bool error);
    public ObsoleteAttribute(string message);
    public ObsoleteAttribute();
    public bool IsError{ get; }
    public string Message{ get; }
}

3.构建自定义特性

public sealed class VehicleDescriptionAttribute : System.Attribute
{
    public string Description { get; set; }
    public VehicleDescriptionAttribute(string vehicalDescription)
    {
        Description = vehicalDescription;
    }

    public VehicleDescriptionAttribute()
    {
    }
}

[Serializable]
[VehicleDescription(Description="My rocking Harley")]
public class Motorcycle
{
}

[SerializableAttribute]
[ObsoleteAttribute("Use another vehicle!")]
[VehicleDescription("The old gray mare, she ain't what she used to be...")]
public class HorseAndBuggy
{
}

[VehicleDescription("A very long,slow, but feature-rich auto")]
public class Winnebago
{
}

public enum AttributeTargets
{
    All,
    Assembly,
    Class,
    Constructor,
    Delegate,
    Enum,
    Event,
    Field,
    GenericParameter,
    Interface,
    Method,
    Module,
    Parameter,
    Property,
    ReturnValue,
    Struct
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]
public sealed class VehicleDescriptionAttribute : System.Attribute
{
    ...
}

4.程序集级别特性
程序集或模块级别特性须在命名空间外定义。

猜你喜欢

转载自blog.csdn.net/x13262608581/article/details/82050434