clr via c# 程序集加载和反射集(一)
2021-03-20 05:23
标签:定时 enumerate member attribute 获取 sel draw rate eterm 结果: s7.net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d5812d469e84c693‘s types: 要获取的类型的程序集限定名称。 请参阅 AssemblyQualifiedName。 如果该类型位于当前正在执行的程序集中或者 Mscorlib.dll 中,则提供由命名空间限定的类型名称就足够了。 System.TypeInfo提供了实列成员DeclaredNestedTypes和GetDeclaredNestedType定义了类中嵌套的类型. System.Reflection.Assembly 类型提供了实列成员 GetType \\string,输入的类型的全名 DefinedTypes \\ 返回所有定义的类型的TypeInfo. ExportedTypes\\返回所有定义的公共类型 type对象是轻量级引用,需要更多的了解类型本身,必须获取一个TypeInfo对象 {Name{0},PublicKeyToken={1},version={2},Culture={3}} System.Reflection.MemberInfo 创建类的实列,Invoke类的实列调用类的构造器时使用. 指定当前类上面声明的成员 指定未定义任何绑定标志。 未知... 指定应返回层次结构往上的公共成员和受保护静态成员。. 静态成员包括字段、方法、事件和属性。. 不支持嵌套类型。 指定应返回指定字段的值。此标志会传递给 指定应返回指定属性的值。此标志会传递给 指定在绑定时不应考虑成员名称的大小写。 在 COM
互操作中用于指定可以忽略成员的返回值。 指定实例成员要包括在搜索中。 指定要调用的方法。非构造器 此标志会传递给 指定非公共成员要包括在搜索中。 返回其参数计数与提供的参数数量匹配的成员集。 此绑定标志用于参数具有默认值的方法和使用变量参数 (varargs)
的方法。此标志只应与 InvokeMember(String, BindingFlags, Binder, Object,
Object[], ParameterModifier[], CultureInfo, String[]) 结合使用。 指定公共成员要包括在搜索中。 指定应调用 COM 对象上的 指定应调用 COM 对象上的 指定应设置指定字段的值。 指定应设置指定属性的值。 指定静态成员要包括在搜索中。 未实现。 上面的列子枚举了差不多的一些反射调用一个类中的方法或者字段或者其他的一些用法 Binder用来自定义选择匹配的方法,字段等...一般不用,或者使用Type.DefaultBinder使用. 通过反射构造类的实列常用方法: 在使用过程中发现System.IO.FileLoadException错误,的原因为: 我因为忘记给HostSDK进行强名称设定,所以出错.HostSDK进行之后,AddIn也要进行. 1,设计接口类: 2,设计接口实现类 3,进行编译dll 4,在程序中使用 clr via c# 程序集加载和反射集(一) 标签:定时 enumerate member attribute 获取 sel draw rate eterm 原文地址:https://www.cnblogs.com/frogkiller/p/12310395.html1,程序集加载---弱的程序集可以加载强签名的程序集,但是不可相反.否则引用会报错!(但是,反射是没问题的)
//获取当前类的Assembly
Assembly.GetEntryAssembly()
//通过Load方法加载程序集
Assembly.Load
//通过LoadFrom加载指定路径名的程序集--可以时url对象.
Assembly LoadFrom(string path)
//只是反射,并确保程序集中的数据不被执行.
ReflectionOnlyLoadFrom()
ReflectionOnlyLoad(string assembly string)
2,发现程序集中定义的类型
class ReflectionRef
{
public static void Demo1()
{
string AssemblyName = "s7.net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d5812d469e84c693, processorArchitecture=MSIL";
Assembly a = Assembly.Load(AssemblyName);
Display(0, "{0}‘s types:",a.FullName);
a.ExportedTypes.ToList().ForEach(x => Display(2, "t‘s FullName is {0}", x.FullName));
Console.WriteLine();
a = Assembly.GetEntryAssembly();
Display(0, "{0}‘s types:", a.FullName);
a.ExportedTypes.ToList().ForEach(x => Display(2, "t‘s FullName is {0}", x.FullName));
}
private static void Display(int indent,string Format,params object[] obj)
{
Console.Write(new string(‘ ‘, indent * 2));
Console.WriteLine(Format, obj);
}
}
t‘s FullName is S7.Net.TcpClientMixins
t‘s FullName is S7.Net.Conversion
2,类型对象的准确含义.//通过实列获得类型
obj.GetType();
//通过Type类的静态函数GetType()
public static Type GetType (string typeName);//必须是FullName
//是否抛出异常和忽略大小写.
public static Type GetType (string typeName, bool throwOnError, bool ignoreCase);
//
参数
public virtual System.Collections.Generic.IEnumerable
public virtual System.Collections.Generic.IEnumerable
TypeInfo ti = typeof(ReflectionRef).GetTypeInfo();
3,通过反射构建派生类的层次结构
private static void LoadAssemblies()
{
String[] assemblies =
{
"System, PublicKeyToken={0}",
"System.Core, PublicKeyToken={0}",
"System.Data, PublicKeyToken={0}",
"System.Design, PublicKeyToken={1}",
"System.DirectoryServices, PublicKeyToken={1}",
"System.Drawing, PublicKeyToken={1}",
"System.Drawing.Design, PublicKeyToken={1}",
"System.Management, PublicKeyToken={1}",
"System.Messaging, PublicKeyToken={1}",
"System.Runtime.Remoting, PublicKeyToken={0}",
"System.Security, PublicKeyToken={1}",
"System.ServiceProcess, PublicKeyToken={1}",
"System.Web, PublicKeyToken={1}",
"System.Web.RegularExpressions, PublicKeyToken={1}",
"System.Web.Services, PublicKeyToken={1}",
"System.Windows.Forms, PublicKeyToken={0}",
"System.Xml, PublicKeyToken={0}",
};
String EcmaPublicKeyToken = "b77a5c561934e089";
String MSPublicKeyToken = "b03f5f7f11d50a3a";
// Get the version of the assembly containing System.Object
// We‘ll assume the same version for all the other assemblies
Version version = typeof(System.Object).Assembly.GetName().Version;
// Explicitly load the assemblies that we want to reflect over
foreach (String a in assemblies)
{
String AssemblyIdentity =
String.Format(a, EcmaPublicKeyToken, MSPublicKeyToken) +
", Culture=neutral, Version=" + version;
Assembly.Load(AssemblyIdentity);//在AppDomain中加载程序集
}
}
public static void Demo2()
{
Assembly[] oldAssembly = AppDomain.CurrentDomain.GetAssemblies();//未加载程序集时的app Domain中的程序集
LoadAssemblies();//加载程序集
var newAssemblyName = (from a in AppDomain.CurrentDomain.GetAssemblies()//获取在原程序集中的程序集
where Array.IndexOf(oldAssembly, a) >= 0
orderby a.FullName
select a.FullName).ToArray();
Array.ForEachstring>(newAssemblyName, x => Display(3, x));//打印原程序集
Console.WriteLine("Compare Assemblys end");
var allTypes =
(from a in AppDomain.CurrentDomain.GetAssemblies()
from t in a.ExportedTypes
where typeof(MemberInfo).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo())//获取所有派生自Exception的类型.
orderby t.Name
select t).ToArray();
Display(0, WalkInheritanceHierachy(new StringBuilder(), 0, typeof(MemberInfo), allTypes).ToString());//迭代打印这些类型.
}
private static StringBuilder WalkInheritanceHierachy(StringBuilder sb,int indent,Type baseType,IEnumerable
System.Reflection.EventInfo
System.Runtime.InteropServices.ComAwareEventInfo
System.Reflection.FieldInfo
System.Reflection.Emit.FieldBuilder
System.Reflection.MethodBase
System.Reflection.ConstructorInfo
System.Reflection.Emit.ConstructorBuilder
System.Reflection.MethodInfo
System.Reflection.Emit.DynamicMethod
System.Reflection.Emit.MethodBuilder
System.Reflection.PropertyInfo
System.Reflection.Emit.PropertyBuilder
System.Type
System.Reflection.TypeInfo
System.Reflection.Emit.EnumBuilder
System.Reflection.Emit.GenericTypeParameterBuilder
System.Reflection.Emit.TypeBuilder
System.Reflection.TypeDelegator4,BindingFlags
字段
CreateInstance
512
DeclaredOnly
2
Default
0
DoNotWrapExceptions
33554432
ExactBinding
65536
FlattenHierarchy
64
GetField
1024
InvokeMember
方法以获取字段值。
GetProperty
4096
InvokeMember
方法以调用属性
IgnoreCase
1
IgnoreReturn
16777216
Instance
4
InvokeMethod
256
InvokeMember
方法以调用方法。
NonPublic
32
OptionalParamBinding
262144
使用默认值的参数仅在省略了尾随参数的调用中使用。Parameters with default values
are used only in calls where trailing arguments are omitted. 它们必须是位于最后面的参数。They must be the last
arguments.
Public
16
PutDispProperty
16384
PROPPUT
成员。
PutRefDispProperty
32768
PROPPUTREF
成员。
SetField
2048
SetProperty
8192
Static
8
SuppressChangeType
131072
public class BindingFlagsRef
{
public static void Go()
{
// BindingFlags.InvokeMethod
// Call a static method.
Type t = typeof(TestClass);
Console.WriteLine();
Console.WriteLine("Invoking a static method.");
Console.WriteLine("-------------------------");
t.InvokeMember("SayHello", BindingFlags.InvokeMethod | BindingFlags.Public |//调用类的静态方法.注意Binder=null,Target=null
BindingFlags.Static, null, null, new object[] { });
// BindingFlags.InvokeMethod
// Call an instance method.
TestClass c = new TestClass();
Console.WriteLine();
Console.WriteLine("Invoking an instance method.");
Console.WriteLine("----------------------------");
c.GetType().InvokeMember("AddUp", BindingFlags.InvokeMethod, null, c, new object[] { });//调用实列的方法,注意,Target=c;
c.GetType().InvokeMember("AddUp", BindingFlags.InvokeMethod, null, c, new object[] { });//调用实列的方法,注意,Target=c;
// BindingFlags.InvokeMethod
// Call a method with parameters.
object[] args = new object[] { 100.09, 184.45 };
object result;
Console.WriteLine();
Console.WriteLine("Invoking a method with parameters.");
Console.WriteLine("---------------------------------");
result = t.InvokeMember("ComputeSum", BindingFlags.InvokeMethod , null, null, args);//调用带参数的方法.
Console.WriteLine("{0} + {1} = {2}", args[0], args[1], result);
// BindingFlags.GetField, SetField
Console.WriteLine();
Console.WriteLine("Invoking a field (getting and setting.)");
Console.WriteLine("--------------------------------------");
// Get a field value.
result = t.InvokeMember("Name", BindingFlags.GetField, null, c, new object[] { });//获取和设定字段.
Console.WriteLine("Name == {0}", result);
// Set a field.
t.InvokeMember("Name", BindingFlags.SetField, null, c, new object[] { "NewName" });
result = t.InvokeMember("Name", BindingFlags.GetField, null, c, new object[] { });
Console.WriteLine("Name == {0}", result);
Console.WriteLine();
Console.WriteLine("Invoking an indexed property (getting and setting.)");
Console.WriteLine("--------------------------------------------------");
// BindingFlags.GetProperty
// Get an indexed property value.
int index = 3;
result = t.InvokeMember("Item", BindingFlags.GetProperty, null, c, new object[] { index });//获取索引器的值.
Console.WriteLine("Item[{0}] == {1}", index, result);
// BindingFlags.SetProperty
// Set an indexed property value.
index = 3;
t.InvokeMember("Item", BindingFlags.SetProperty, null, c, new object[] { index, "NewValue" });//设定索引器的值.
result = t.InvokeMember("Item", BindingFlags.GetProperty, null, c, new object[] { index });
Console.WriteLine("Item[{0}] == {1}", index, result);
Console.WriteLine();
Console.WriteLine("Getting a field or property.");
Console.WriteLine("----------------------------");
// BindingFlags.GetField
// Get a field or property.
result = t.InvokeMember("Name", BindingFlags.GetField | BindingFlags.GetProperty, null, c,
new object[] { });
Console.WriteLine("Name == {0}", result);//获取属性或者字段的对象.
// BindingFlags.GetProperty
result = t.InvokeMember("Value", BindingFlags.GetField | BindingFlags.GetProperty, null, c,
new object[] { });//获取属性或者字段的对象.
Console.WriteLine("Value == {0}", result);
Console.WriteLine();
Console.WriteLine("Invoking a method with named parameters.");
Console.WriteLine("---------------------------------------");
// BindingFlags.InvokeMethod
// Call a method using named parameters.
object[] argValues = new object[] { "Mouse", "Micky" };
String[] argNames = new String[] { "lastName", "firstName" };
t.InvokeMember("PrintName", BindingFlags.InvokeMethod, null, null, argValues, null, null,//指定Named类型的方法.
argNames);
Console.WriteLine();
Console.WriteLine("Invoking a default member of a type.");
Console.WriteLine("------------------------------------");
// BindingFlags.Default
// Call the default member of a type.
Type t3 = typeof(TestClass2);
t3.InvokeMember("", BindingFlags.InvokeMethod | BindingFlags.Default, null, new TestClass2(),
new object[] { });//利用特性MemberDefault,和反射配合指定使用方法.当前是Print.
// BindingFlags.Static, NonPublic, and Public
// Invoking a member with ref parameters.
Console.WriteLine();
Console.WriteLine("Invoking a method with ref parameters.");
Console.WriteLine("--------------------------------------");
MethodInfo m = t.GetMethod("Swap");
args = new object[2];
args[0] = 1;
args[1] = 2;
//m.Invoke(new TestClass(), args);//和调用有参的形式一样,这是新的办法
t.InvokeMember("Swap", BindingFlags.InvokeMethod, null, new TestClass(), args);//这是通过type来调用.
Console.WriteLine("{0}, {1}", args[0], args[1]);
// BindingFlags.CreateInstance
// Creating an instance with a parameterless constructor.
Console.WriteLine();
Console.WriteLine("Creating an instance with a parameterless constructor.");
Console.WriteLine("------------------------------------------------------");
object cobj = t.InvokeMember("TestClass", BindingFlags.Public |//注意3个BindingFlags的应用.
BindingFlags.Instance | BindingFlags.CreateInstance,
null, null, new object[] { });//创建类的实列的另外一个办法.
Console.WriteLine("Instance of {0} created.", cobj.GetType().Name);
// Creating an instance with a constructor that has parameters.
Console.WriteLine();
Console.WriteLine("Creating an instance with a constructor that has parameters.");
Console.WriteLine("------------------------------------------------------------");
cobj = t.InvokeMember("TestClass", BindingFlags.Public |//创建有参的构造器,并且返回实列.
BindingFlags.Instance | BindingFlags.CreateInstance,
null, null, new object[] { "Hello, World!" });
Console.WriteLine("Instance of {0} created with initial value ‘{1}‘.", cobj.GetType().Name,
cobj.GetType().InvokeMember("Name", BindingFlags.GetField, null, cobj, null));
// BindingFlags.DeclaredOnly
Console.WriteLine();
Console.WriteLine("DeclaredOnly instance members.");
Console.WriteLine("------------------------------");
System.Reflection.MemberInfo[] memInfo =
t.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance |//考虑在本类中创建(非继承,实列,公共)的成员集合.
BindingFlags.Public);
for (int i = 0; i // BindingFlags.IgnoreCase
Console.WriteLine();
Console.WriteLine("Using IgnoreCase and invoking the PrintName method.");
Console.WriteLine("---------------------------------------------------");
t.InvokeMember("printname", BindingFlags.IgnoreCase | BindingFlags.Static |//忽略大小写
BindingFlags.Public | BindingFlags.InvokeMethod, null, null, new object[]
{"Brad","Smith"});
// BindingFlags.FlattenHierarchy
Console.WriteLine();
Console.WriteLine("Using FlattenHierarchy to get inherited static protected and public members.");
Console.WriteLine("----------------------------------------------------------------------------");
FieldInfo[] finfos = typeof(MostDerived).GetFields(BindingFlags.NonPublic | BindingFlags.Public |//NoPublic是Protected对象.
BindingFlags.Static | BindingFlags.FlattenHierarchy);//返回受保护静态成员.
foreach (FieldInfo finfo in finfos)
{
Console.WriteLine("{0} defined in {1}.", finfo.Name, finfo.DeclaringType.Name);//DeclaringType...成员所定义的Type
}
Console.WriteLine();
Console.WriteLine("Without FlattenHierarchy.");
Console.WriteLine("-------------------------");
finfos = typeof(MostDerived).GetFields(BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Static);
foreach (FieldInfo finfo in finfos)
{
Console.WriteLine("{0} defined in {1}.", finfo.Name, finfo.DeclaringType.Name);
}
}
}
public class TestClass
{
public String Name;
private Object[] values = new Object[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
public Object this[int index]
{
get
{
return values[index];
}
set
{
values[index] = value;
}
}
public Object Value
{
get
{
return "the value";
}
}
public TestClass() : this("initialName") { }
public TestClass(string initName)
{
Name = initName;
}
int methodCalled = 0;
public static void SayHello()
{
Console.WriteLine("Hello");
}
public void AddUp()
{
methodCalled++;
Console.WriteLine("AddUp Called {0} times", methodCalled);
}
public static double ComputeSum(double d1, double d2)
{
return d1 + d2;
}
public static void PrintName(String firstName, String lastName)
{
Console.WriteLine("{0},{1}", lastName, firstName);
}
public void PrintTime()
{
Console.WriteLine(DateTime.Now);
}
public void Swap(ref int a, ref int b)
{
int x = a;
a = b;
b = x;
}
}
[DefaultMemberAttribute("PrintTime")]
public class TestClass2
{
public void PrintTime()
{
Console.WriteLine(DateTime.Now);
}
}
public class Base
{
static int BaseOnlyPrivate = 0;
protected static int BaseOnly = 0;
}
public class Derived : Base
{
public static int DerivedOnly = 0;
}
public class MostDerived : Derived { }
5,Binder-----从候选者列表中选择一个成员,并执行实参类型到形参类型的类型转换,需要实现派生
6,构造类的实列
public static void CallCreateObjectByReflection()
{
//方法1,使用createInstance--type方法.
Type t = typeof(TestClass);
TestClass t1 = (TestClass)Activator.CreateInstance(t, new object[] { });
Display(0, t1.Name);
//方法2,使用程序集的方法,第一个参数可以是null,当前程序集,或者是Assembly.GetEnterAssembly.ToString(),返回程序集的全名.
var t2 = (TestClass)Activator.CreateInstance(null, typeof(TestClass).FullName).Unwrap();
Display(0, Assembly.GetEntryAssembly().ToString());
Display(0, t2.Name);
//方法3,使用CreateInstanceFrom生成.
var path = Assembly.GetEntryAssembly().CodeBase;
var t3 = (TestClass)Activator.CreateComInstanceFrom(path, typeof(TestClass).FullName).Unwrap();
Display(0, "path is {0},type is {1}", path, t3);
//方法4,使用AppDomain的CreateInstance;注意,如果是另外的appDomain则需要类型是MarshalRefObject的派生类,或者可序列化对象.
AppDomain ad0 = AppDomain.CreateDomain("Ad0");
var t4=AppDomain.CurrentDomain.CreateInstanceFromAndUnwrap(path, typeof(TestClass).FullName);
Display(0, "path is {0},type is {1}", path, t4);
//方法5,使用InVokeMember调用构造器.
var t5 = (TestClass)t.InvokeMember("", BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, null);
Display(0, t5.Name);
//方法6,使用ConstructorInfo,其实类似上面的
ConstructorInfo ci = t.GetConstructor(new Type[] { typeof(string) });
var t6=(TestClass)ci.Invoke(new object[] { "new Constructor" });
Display(0, t6.Name);
//方法7,数组类型创建实列
Array t7 = Array.CreateInstance(t, 10);
for(int i=0;i
7,设计支持加载项的程序.
//HostSDK.cs
using System;
namespace Winteliect.HostSDK
{
public interface IAddin
{
string DoSomeThing(Int32 x);
}
}
//AddInTypes.cs
using System;
using Winteliect.HostSDK;
namespace AddInTypes
{
public sealed class AddIn_A:IAddin
{
public AddIn_A(){}
public string DoSomeThing(Int32 x)
{
return "AddIn_A:"+x.ToString();
}
}
public sealed class AddIn_B:IAddin
{
public AddIn_B(){}
public string DoSomeThing(Int32 x)
{
return "AddIn_B:"+(2*x).ToString();
}
}
}
public static void DynamicLoadDemo()
{
string path = Assembly.GetExecutingAssembly().Location;//获取.exe的详细路径
string AddInDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);//获取.exe的目录.../Debug
var dlls = Directory.EnumerateFiles(AddInDir, "*.dll");//
var types =
(from file in dlls
let asb = Assembly.LoadFrom(file)
from t in asb.ExportedTypes
where t.IsPublic && t.IsClass && (typeof(IAddin).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo()))
select t).ToList();//获取有该接口的类.
types.ForEach(//创建类的实列并且工作.
x =>
{
IAddin t = (IAddin)Activator.CreateInstance(x);
Display(0,t.DoSomeThing(10));
});
}