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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...