clr via c# 程式集載入和反射集(一)

来源:https://www.cnblogs.com/frogkiller/archive/2020/02/15/12310395.html
-Advertisement-
Play Games

1,程式集載入 弱的程式集可以載入強簽名的程式集,但是不可相反.否則引用會報錯!(但是,反射是沒問題的) //獲取當前類的Assembly Assembly.GetEntryAssembly() //通過Load方法載入程式集 Assembly.Load //通過LoadFrom載入指定路徑名的程式 ...


1,程式集載入---弱的程式集可以載入強簽名的程式集,但是不可相反.否則引用會報錯!(但是,反射是沒問題的)

//獲取當前類的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);
        }

    }

結果:

s7.net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d5812d469e84c693's types:
     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);
//
參數
typeName
String

要獲取的類型的程式集限定名稱。 請參閱 AssemblyQualifiedName。 如果該類型位於當前正在執行的程式集中或者 Mscorlib.dll 中,則提供由命名空間限定的類型名稱就足夠了。

System.TypeInfo提供了實列成員DeclaredNestedTypes和GetDeclaredNestedType定義了類中嵌套的類型.

System.Reflection.Assembly 類型提供了實列成員

GetType  \\string,輸入的類型的全名

DefinedTypes \\ 返回所有定義的類型的TypeInfo.

public virtual System.Collections.Generic.IEnumerable<System.Reflection.TypeInfo> DefinedTypes { get; }

ExportedTypes\\返回所有定義的公共類型

public virtual System.Collections.Generic.IEnumerable<Type> ExportedTypes { get; }

type對象是輕量級引用,需要更多的瞭解類型本身,必須獲取一個TypeInfo對象

TypeInfo ti = typeof(ReflectionRef).GetTypeInfo();

 

  • IsPublic
  • IsSealed
  • IsAbstract
  • IsClass
  • IsValueType
  • 另一些參數返回:
  • Assembly
  • AssemblyQulifiedName
  • FullName
  • Module

3,通過反射構建派生類的層次結構

  • 批量載入程式集---註意,載入程式集的四個要素

{Name{0},PublicKeyToken={1},version={2},Culture={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.ForEach<string>(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<Type> allTypes)//迭代列印函數
        {
            string spaces = new string(' ', indent * 3);//首碼空格
            sb.AppendLine(spaces + baseType.FullName);//添加基類的全名,新一行.
            foreach(var t in allTypes)
            {
                if (t.GetTypeInfo().BaseType != baseType) continue;//如果這個類不是另一個類的基列,繼續.
                WalkInheritanceHierachy(sb, indent + 1, t, allTypes);//如果找到某個類是派生類,則將這個類作為基類,去查找新的派生類.
            }
            return sb;
        }
  • 結果:

System.Reflection.MemberInfo
    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.TypeDelegator

4,BindingFlags

欄位

 

CreateInstance 512

創建類的實列,Invoke類的實列調用類的構造器時使用.

 

DeclaredOnly 2

指定當前類上面聲明的成員

Default 0

指定未定義任何綁定標誌。

DoNotWrapExceptions 33554432  
ExactBinding 65536

未知...

FlattenHierarchy 64

指定應返回層次結構往上的公共成員和受保護靜態成員。. 靜態成員包括欄位、方法、事件和屬性。. 不支持嵌套類型。

GetField 1024

指定應返回指定欄位的值。此標誌會傳遞給 InvokeMember 方法以獲取欄位值。

GetProperty 4096

指定應返回指定屬性的值。此標誌會傳遞給 InvokeMember 方法以調用屬性

IgnoreCase 1

指定在綁定時不應考慮成員名稱的大小寫。

IgnoreReturn 16777216

在 COM 互操作中用於指定可以忽略成員的返回值。

Instance 4

指定實例成員要包括在搜索中。

InvokeMethod 256

指定要調用的方法。非構造器

此標誌會傳遞給 InvokeMember 方法以調用方法。

NonPublic 32

指定非公共成員要包括在搜索中。

OptionalParamBinding 262144

返回其參數計數與提供的參數數量匹配的成員集。

此綁定標誌用於參數具有預設值的方法和使用變數參數 (varargs) 的方法。此標誌只應與 InvokeMember(String, BindingFlags, Binder, Object, Object[], ParameterModifier[], CultureInfo, String[]) 結合使用。
使用預設值的參數僅在省略了尾隨參數的調用中使用。Parameters with default values are used only in calls where trailing arguments are omitted. 它們必須是位於最後面的參數。
They must be the last arguments.

Public 16

指定公共成員要包括在搜索中。

PutDispProperty 16384

指定應調用 COM 對象上的 PROPPUT 成員。

PutRefDispProperty 32768

指定應調用 COM 對象上的 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 < memInfo.Length; i++)
            {
                Console.WriteLine(memInfo[i].Name);
            }

            // 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-----從候選者列表中選擇一個成員,並執行實參類型到形參類型的類型轉換,需要實現派生

   Binder用來自定義選擇匹配的方法,欄位等...一般不用,或者使用Type.DefaultBinder使用.

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<t7.Length;i++)
            {
                t7.SetValue(new TestClass(i.ToString()), i);
            }
            int count=0;
            Array.ForEach<TestClass>((TestClass[])t7, x => Display(count++, x.Name));
            //方法7_1,另外一個方法創建數組的實列.
            Type t71 = t.MakeArrayType();
            var t72 =(TestClass[]) Activator.CreateInstance(t71, new object[] { 10 });
            Display(0, t72.Length.ToString());

            //方法8,委托類型創建實列
            MethodInfo mi = t.GetMethod("AddUp");
            var t8 = new TestClass();
            Delegate d = Delegate.CreateDelegate(typeof(Action), t8, mi);
            d.DynamicInvoke();
            d.DynamicInvoke();

            //方法9,構造泛型實列
            Type openType = typeof(Dictionary<,>);//首先創建openType
            Type closeType = openType.MakeGenericType(typeof(string),typeof(string));//創建封閉Type
            Type ListOpenType = typeof(List<>);//創建新的OpenType
            Type ListCloseType = ListOpenType.MakeGenericType(closeType);//創建複合的封閉對象
            object o = Activator.CreateInstance(ListCloseType);//創建類型對象的實列.
            Display(0, o.ToString());


        }

    }

7,設計支持載入項的程式.

    Rainbow  在使用過程中發現System.IO.FileLoadException錯誤,的原因為:

  • 如果某個類是強名稱,那麼所有它引用的類也必須都是強名稱.

        我因為忘記給HostSDK進行強名稱設定,所以出錯.HostSDK進行之後,AddIn也要進行.

     1,設計介面類:

//HostSDK.cs
using System;

namespace Winteliect.HostSDK
{
	public interface IAddin
	{
		string DoSomeThing(Int32 x);

	}

}

  2,設計介面實現類

//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();
		}
	}
}

      3,進行編譯dll

  • sn -k host.snk
  • csc.exe /out:HostSDK.dll /t:library /keyfile:host.snk HostSDK.cs---生成HostSDK.dll
  • csc.exe /out:AddInTypes.dll /t:library /r:HostSDK.dll /keyfile:host.snk AddInTypes.cs---生成AddInTypes.dll

      4,在程式中使用

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 

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 建議使用format()方法 字元串操作 對於 , 官方以及給出這種格式化操作已經過時,在 的未來版本中可能會消失。 在新代碼中使用新的字元串格式。因此推薦大家使用 來替換 %. format 方法系統複雜變數替換和格式化的能力,因此接下來看看都有哪些用法。 format() 這個方法是來自 模塊的 ...
  • 在使用Eclipse過程中可能想更換下界面主題,此處介紹的是一款主題插件 Eclipse Color Theme 打開Eclipse,Help --> Eclipse Marketplace 在打開的視窗中 搜索 theme 在搜索結果中選擇 Eclipse Color Theme 並安裝,安裝過程 ...
  • 史上最水的 dp 題,沒有之一(By rxz) 確實很簡單,就算是我這個 dp 萌新也一眼看出來了轉移方程 首先考慮狀態,設 $f_{i,j}$ 表示選擇第 $i$ 層第 $j$ 個數時獲得的最大值,那麼可以發現,對於數字 $a_{i,j}$ ,只有從 $a_{i 1,j}$ 和 $a_{i 1,j ...
  • 數轉換成二叉樹:使用孩子兄弟表示法。 二叉樹轉換成樹:將二叉樹的右孩子轉換成兄弟。 森林轉換成二叉樹:將森林中的每一棵樹都轉換成二叉樹,然後把森林中每個結點連起來,調整角度,使其成為二叉樹形狀。 二叉樹轉換成森林:將二叉樹分成n個互不相交、沒有右子樹的二叉樹,然後將每個二叉樹都轉換成樹。 ...
  • 題目大意:給定 $n$ 個數,每次可以 任意 選兩個數 $a_i,a_j$ 相加,把相加的結果作為一個新數繼續執行此操作,直到只剩一個數為止。現要求使最後得出的這個數最小。 一個顯然的貪心策略:每次選最小的兩個數相加,得到一個新數,然後繼續。但是,如果按照這樣的思路,那麼每次得到新數後這個序列的 單 ...
  • 讀題易得:對於有邊的兩個點 $u,v$ ,能且僅能其中一點對這條邊進行封鎖。 什麼意思呢?假設給這張圖上的點進行染色,那麼對於上述的兩個點 $u,v$ , $u,v$ 必須異色 (理解這一點很重要)。 那麼,也就是說,在這張圖上,如果要把這張圖“完全封鎖”且兩隻河蟹不能封鎖相鄰的兩個點,換而言之,把 ...
  • 非嚴格定義:在一棵帶權樹上, 相聚距離最大的兩個點 或 最長鏈 的長度,稱之為 樹的直徑 樣例輸入: 樣例輸出 似乎並沒有什麼難理解的地方。 解法1:DP 咕著 解法2:DFS 經過思考,發現一個重要的性質: 離樹上的某一結點最遠的那個結點,定是直徑的一個端點。 那麼就好辦了!找到任一點的最遠點,再 ...
  • 使用SpringCloud做集群,開發、測試階段,經常要運行一個模塊的多個實例,要修改埠號。 有3種方式。 方式一:配置文件 server.port=9001 方式二、修改引導類,控制台輸入參數值 @SpringBootApplication @EnableEurekaServer //作為Eur ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...