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

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

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 

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

更多相關文章
  • 建議使用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 ...
一周排行
  • 微信公眾號dotnet跨平臺2020年初做的一個關於中國.NET開發者調查收到了開發者近 1400 條回覆。這份調查報告涵蓋了開發者工具鏈的所有部分,包括編程語言、應用架構、應用伺服器、運行時平臺、框架技術、框架配置、IDE、.NET/.NET Core 發行版部署模式、構建工具和Kubernete... ...
  • Winform控制項的雙緩衝。控制項的雙緩衝屬性是隱藏的,可以通過反射改變其屬性值。 lv.GetType().GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(lv, true, ...
  • 1. 需求 上圖這種包含多選(CheckBox)和單選(RadioButton)的菜單十分常見,可是在WPF中只提供了多選的MenuItem。順便一提,要使MenuItem可以多選,只需要將MenuItem的 屬性設置為True: 不知出於何種考慮,WPF沒有為MenuItem提供單選的功能。為了在 ...
  • gRPC的結構 在我們搭建gRPC通信系統之前,首先需要知道gRPC的結構組成。 首先,需要一個server(伺服器),它用來接收和處理請求,然後返迴響應。 既然有server,那麼肯定有client(客戶端),client的作用就是向server發送請求,具體就是生成一個請求,然後把它發送到ser ...
  • 區別 OpenId: Authentication :認證 Oauth: Aurhorize :授權 輸入賬號密碼,QQ確認輸入了正確的賬號密碼可以登錄 認證 下麵需要勾選的覆選框(獲取昵稱、頭像、性別) 授權 OpenID 當你需要訪問A網站的時候,A網站要求你輸入你的OpenId,即可跳轉到你的 ...
  • 前言 預計是通過三篇來將清楚asp.net core 3.x中的授權:1、基本概念介紹;2、asp.net core 3.x中授權的預設流程;3、擴展。 在完全沒有概念的情況下無論是看官方文檔還是源碼都暈乎乎的,希望本文能幫到你。不過我也是看源碼結合官方文檔看的,可能有些地方理解不對,所以只作為參考 ...
  • 簡介 基於生產者消費者模式,我們可以開發出線程安全的非同步消息隊列。 知識儲備 什麼是生產者消費者模式? 為了方便理解,我們暫時將它理解為垃圾的產生到結束的過程。 簡單來說,多住戶產生垃圾(生產者)將垃圾投遞到全小區唯一一個垃圾桶(單隊列),環衛將垃圾桶中的垃圾進行處理(消費者)。就是一個生產者消費者 ...
  • 很多時候,需要對類中的方法進行一些測試,來判斷是否能按要求輸出預期的結果。 C#提供了快速創建單元測試的方法,但單元測試不僅速度慢不方便,大量的單元測試還會拖慢項目的啟動速度。 所以決定自己搞個方便的測試用例。 控制台一句話調用。 測試用例.註冊並Print(EnumEx.Name); 結果畫面: ...
  • 常成員函數不能改變數據成員的值,例如定義坐標類Coordinate,成員函數changeX():void Coordinate::changeX(){ x = 10;}雖然changeX()沒有參數,但是它隱含一個參數——this指針:void Coordinate::changeX(Coordin... ...
  • 因為新冠肺炎疫情,診所還沒復工。這是在家用手機敲的,代碼顯示有問題。等復工以後在電腦上改,各位先湊和看吧。 支持向量機(Support Vector Machine, SVM)是一種基於統計學習的模式識別的分類方法,主要用於模式識別。所謂支持向量指的是在分割區域邊緣的訓練樣本點,機是指演算法。就是要找 ...
x