AppDomain.CreateInstanceAndUnwrap 方法

定义

创建指定类型的新实例。

重载

CreateInstanceAndUnwrap(String, String)

创建指定类型的新实例。 参数指定在其中定义类型的程序集以及类型的名称。

CreateInstanceAndUnwrap(String, String, Object[])

创建指定类型的新实例。 参数指定在其中定义类型的程序集、类型的名称和激活属性数组。

CreateInstanceAndUnwrap(String, String, Boolean, BindingFlags, Binder, Object[], CultureInfo, Object[])

创建指定程序集中定义的指定类型的新实例,指定是否忽略类型名称大小写;用于选择要创建的类型的绑定属性和绑定器;构造函数的参数;区域性;和激活属性。

CreateInstanceAndUnwrap(String, String, Boolean, BindingFlags, Binder, Object[], CultureInfo, Object[], Evidence)
已过时.

创建指定类型的新实例。 参数指定类型的名称及其创建方式。

CreateInstanceAndUnwrap(String, String)

Source:
AppDomain.cs
Source:
AppDomain.cs
Source:
AppDomain.cs

创建指定类型的新实例。 参数指定在其中定义类型的程序集以及类型的名称。

C#
public object? CreateInstanceAndUnwrap (string assemblyName, string typeName);
C#
public object CreateInstanceAndUnwrap (string assemblyName, string typeName);

参数

assemblyName
String

程序集的显示名称。 请参阅 FullName

typeName
String

请求类型的完全限定名称,包括命名空间而不是程序集,由 FullName 属性返回。

返回

typeName指定的对象的实例。

例外

assemblyNametypeNamenull

找不到匹配的公共构造函数。

assemblyName中找不到 typeName

找不到 assemblyName

调用方无权调用此构造函数。

在卸载的应用程序域中尝试此操作。

assemblyName 当前加载的运行时不是有效的程序集。

程序集或模块加载了两次,其中包含两个不同的证据。

示例

下面的代码示例演示了在另一个应用程序域中执行代码的最简单方法。 该示例定义一个名为 Worker 的类,该类继承自 MarshalByRefObjectWorker 类定义一个方法,用于显示在其中执行应用程序域的名称。 该示例在默认应用程序域和新应用程序域中创建 Worker 实例。

备注

包含 Worker 的程序集必须加载到这两个应用程序域中,但它可以加载仅存在于新应用程序域中的其他程序集。

C#
using System;
using System.Reflection;

public class CreateInstanceWorker : MarshalByRefObject
{
    public void PrintDomain()
    {
        Console.WriteLine("Object is executing in AppDomain \"{0}\"",
            AppDomain.CurrentDomain.FriendlyName);
    }
}

class CreateInstanceAndUnwrapSourceSnippet
{
    public static void Main()
    {
        // Create an ordinary instance in the current AppDomain
        CreateInstanceWorker localWorker = new CreateInstanceWorker();
        localWorker.PrintDomain();

        // Create a new application domain, create an instance
        // of Worker in the application domain, and execute code
        // there.
        AppDomain ad = AppDomain.CreateDomain("New domain");
        CreateInstanceWorker remoteWorker = (CreateInstanceWorker) ad.CreateInstanceAndUnwrap(
            typeof(CreateInstanceWorker).Assembly.FullName,
            "Worker");
        remoteWorker.PrintDomain();
    }
}

/* This code produces output similar to the following:

Object is executing in AppDomain "source.exe"
Object is executing in AppDomain "New domain"
 */

注解

这是一种将 CreateInstanceObjectHandle.Unwrap相结合的便利方法。 此方法调用 typeName的无参数构造函数。

有关 assemblyName格式,请参阅 AssemblyName。 有关 typeName格式,请参阅 Type.FullName 属性。

备注

如果对 CreateInstanceAndUnwrap返回的 T1 类型的对象的方法 M 进行早期绑定调用,并且该方法对程序集中类型 T2 对象的方法进行早期绑定调用,C 当前程序集或包含 T1的程序集,则程序集 C 将加载到当前应用程序域中。 即使对 T1.M() 的早期绑定调用是在 DynamicMethod的正文或其他动态生成的代码中进行的,也会发生此加载。 如果当前域是默认域,则在进程结束之前,无法卸载程序集 C。 如果当前域稍后尝试加载程序集 C,则加载可能会失败。

另请参阅

适用于

.NET 9 和其他版本
产品 版本
.NET Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1

CreateInstanceAndUnwrap(String, String, Object[])

Source:
AppDomain.cs
Source:
AppDomain.cs
Source:
AppDomain.cs

创建指定类型的新实例。 参数指定在其中定义类型的程序集、类型的名称和激活属性数组。

C#
public object? CreateInstanceAndUnwrap (string assemblyName, string typeName, object?[]? activationAttributes);
C#
public object CreateInstanceAndUnwrap (string assemblyName, string typeName, object[] activationAttributes);

参数

assemblyName
String

程序集的显示名称。 请参阅 FullName

typeName
String

请求类型的完全限定名称,包括命名空间而不是程序集,由 FullName 属性返回。

activationAttributes
Object[]

可以参与激活的一个或多个属性的数组。 通常,包含单个 UrlAttribute 对象的数组,该对象指定激活远程对象所需的 URL。

此参数与客户端激活的对象相关。客户端激活是保留的旧技术,用于向后兼容,但不建议用于新开发。 分布式应用程序应改用 Windows Communication Foundation。

返回

typeName指定的对象的实例。

例外

assemblyNametypeNamenull

找不到匹配的公共构造函数。

assemblyName中找不到 typeName

找不到 assemblyName

调用方无权调用此构造函数。

调用方无法为不继承自 MarshalByRefObject的对象提供激活属性。

在卸载的应用程序域中尝试此操作。

assemblyName 当前加载的运行时不是有效的程序集。

程序集或模块加载了两次,其中包含两个不同的证据。

示例

C#
using System;
using System.IO;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.Remoting;

class ADDyno
{
   public static Type CreateADynamicAssembly(ref AppDomain myNewDomain,
                         string executableNameNoExe)
   {
    string executableName = executableNameNoExe + ".exe";

    AssemblyName myAsmName = new AssemblyName();
    myAsmName.Name = executableNameNoExe;
    myAsmName.CodeBase = Environment.CurrentDirectory;

    AssemblyBuilder myAsmBuilder = myNewDomain.DefineDynamicAssembly(myAsmName,
                        AssemblyBuilderAccess.RunAndSave);
    Console.WriteLine("-- Dynamic Assembly instantiated.");

    ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(executableNameNoExe,
                                      executableName);

    TypeBuilder myTypeBuilder = myModBuilder.DefineType(executableNameNoExe,
                        TypeAttributes.Public,
                        typeof(MarshalByRefObject));

    MethodBuilder myFCMethod = myTypeBuilder.DefineMethod("CountLocalFiles",
                        MethodAttributes.Public |
                        MethodAttributes.Static,
                        null,
                        new Type[] {  });

    MethodInfo currentDirGetMI = typeof(Environment).GetProperty("CurrentDirectory").GetGetMethod();
    MethodInfo writeLine0objMI = typeof(Console).GetMethod("WriteLine",
                     new Type[] { typeof(string) });
    MethodInfo writeLine2objMI = typeof(Console).GetMethod("WriteLine",
                     new Type[] { typeof(string), typeof(object), typeof(object) });
    MethodInfo getFilesMI = typeof(Directory).GetMethod("GetFiles",
                new Type[] { typeof(string) });

    myFCMethod.InitLocals = true;

    ILGenerator myFCIL = myFCMethod.GetILGenerator();

    Console.WriteLine("-- Generating MSIL method body...");
    LocalBuilder v0 = myFCIL.DeclareLocal(typeof(string));
    LocalBuilder v1 = myFCIL.DeclareLocal(typeof(int));
    LocalBuilder v2 = myFCIL.DeclareLocal(typeof(string));
    LocalBuilder v3 = myFCIL.DeclareLocal(typeof(string[]));

    Label evalForEachLabel = myFCIL.DefineLabel();
    Label topOfForEachLabel = myFCIL.DefineLabel();

    // Build the method body.

    myFCIL.EmitCall(OpCodes.Call, currentDirGetMI, null);
    myFCIL.Emit(OpCodes.Stloc_S, v0);
    myFCIL.Emit(OpCodes.Ldc_I4_0);
    myFCIL.Emit(OpCodes.Stloc_S, v1);
    myFCIL.Emit(OpCodes.Ldstr, "---");
    myFCIL.EmitCall(OpCodes.Call, writeLine0objMI, null);
    myFCIL.Emit(OpCodes.Ldloc_S, v0);
    myFCIL.EmitCall(OpCodes.Call, getFilesMI, null);
    myFCIL.Emit(OpCodes.Stloc_S, v3);

    myFCIL.Emit(OpCodes.Br_S, evalForEachLabel);

    // foreach loop starts here.
    myFCIL.MarkLabel(topOfForEachLabel);
    
        // Load array of strings and index, store value at index for output.
    myFCIL.Emit(OpCodes.Ldloc_S, v3);
    myFCIL.Emit(OpCodes.Ldloc_S, v1);
    myFCIL.Emit(OpCodes.Ldelem_Ref);
    myFCIL.Emit(OpCodes.Stloc_S, v2);

    myFCIL.Emit(OpCodes.Ldloc_S, v2);
    myFCIL.EmitCall(OpCodes.Call, writeLine0objMI, null);

    // Increment counter by one.
    myFCIL.Emit(OpCodes.Ldloc_S, v1);
    myFCIL.Emit(OpCodes.Ldc_I4_1);
    myFCIL.Emit(OpCodes.Add);
    myFCIL.Emit(OpCodes.Stloc_S, v1);

    // Determine if end of file list array has been reached.
    myFCIL.MarkLabel(evalForEachLabel);
    myFCIL.Emit(OpCodes.Ldloc_S, v1);
    myFCIL.Emit(OpCodes.Ldloc_S, v3);
    myFCIL.Emit(OpCodes.Ldlen);
    myFCIL.Emit(OpCodes.Conv_I4);
    myFCIL.Emit(OpCodes.Blt_S, topOfForEachLabel);
    //foreach loop end here.

    myFCIL.Emit(OpCodes.Ldstr, "---");
    myFCIL.EmitCall(OpCodes.Call, writeLine0objMI, null);
    myFCIL.Emit(OpCodes.Ldstr, "There are {0} files in {1}.");
    myFCIL.Emit(OpCodes.Ldloc_S, v1);
    myFCIL.Emit(OpCodes.Box, typeof(int));
    myFCIL.Emit(OpCodes.Ldloc_S, v0);
    myFCIL.EmitCall(OpCodes.Call, writeLine2objMI, null);

    myFCIL.Emit(OpCodes.Ret);

    Type myType = myTypeBuilder.CreateType();

    myAsmBuilder.SetEntryPoint(myFCMethod);
    myAsmBuilder.Save(executableName);		
    Console.WriteLine("-- Method generated, type completed, and assembly saved to disk.");

    return myType;
   }

   public static void Main()
   {

    string domainDir, executableName = null;
    
    Console.Write("Enter a name for the file counting assembly: ");
    string executableNameNoExe = Console.ReadLine();
    executableName = executableNameNoExe + ".exe";
    Console.WriteLine("---");

    domainDir = Environment.CurrentDirectory;

    AppDomain curDomain = Thread.GetDomain();	

    // Create a new AppDomain, with the current directory as the base.

    Console.WriteLine("Current Directory: {0}", Environment.CurrentDirectory);
    AppDomainSetup mySetupInfo = new AppDomainSetup();
    mySetupInfo.ApplicationBase = domainDir;
    mySetupInfo.ApplicationName = executableNameNoExe;
    mySetupInfo.LoaderOptimization = LoaderOptimization.SingleDomain;

    AppDomain myDomain = AppDomain.CreateDomain(executableNameNoExe,
                    null, mySetupInfo);

    Console.WriteLine("Creating a new AppDomain '{0}'...",
                    executableNameNoExe);

    Console.WriteLine("-- Base Directory = '{0}'", myDomain.BaseDirectory);
    Console.WriteLine("-- Shadow Copy? = '{0}'", myDomain.ShadowCopyFiles);

    Console.WriteLine("---");
    Type myFCType = CreateADynamicAssembly(ref curDomain,
                     executableNameNoExe);

    Console.WriteLine("Loading '{0}' from '{1}'...", executableName,
              myDomain.BaseDirectory.ToString());

    BindingFlags bFlags = (BindingFlags.Public | BindingFlags.CreateInstance |
                   BindingFlags.Instance);

    Object myObjInstance = myDomain.CreateInstanceAndUnwrap(executableNameNoExe,
                executableNameNoExe, false, bFlags,
                null, null, null, null, null);

    Console.WriteLine("Executing method 'CountLocalFiles' in {0}...",
               myObjInstance.ToString());

    myFCType.InvokeMember("CountLocalFiles", BindingFlags.InvokeMethod, null,
                myObjInstance, new object[] { });
   }
}

注解

这是一种将 CreateInstanceObjectHandle.Unwrap相结合的便利方法。 此方法调用 typeName的无参数构造函数。

有关 assemblyName格式,请参阅 AssemblyName。 有关 typeName格式,请参阅 Type.FullName 属性。

备注

如果对 CreateInstanceAndUnwrap返回的 T1 类型的对象的方法 M 进行早期绑定调用,并且该方法对程序集中类型 T2 对象的方法进行早期绑定调用,C 当前程序集或包含 T1的程序集,则程序集 C 将加载到当前应用程序域中。 即使对 T1.M() 的早期绑定调用是在 DynamicMethod的正文或其他动态生成的代码中进行的,也会发生此加载。 如果当前域是默认域,则在进程结束之前,无法卸载程序集 C。 如果当前域稍后尝试加载程序集 C,则加载可能会失败。

另请参阅

适用于

.NET 9 和其他版本
产品 版本
.NET Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1

CreateInstanceAndUnwrap(String, String, Boolean, BindingFlags, Binder, Object[], CultureInfo, Object[])

Source:
AppDomain.cs
Source:
AppDomain.cs
Source:
AppDomain.cs

创建指定程序集中定义的指定类型的新实例,指定是否忽略类型名称大小写;用于选择要创建的类型的绑定属性和绑定器;构造函数的参数;区域性;和激活属性。

C#
public object? CreateInstanceAndUnwrap (string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes);
C#
public object CreateInstanceAndUnwrap (string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture, object[] activationAttributes);

参数

assemblyName
String

程序集的显示名称。 请参阅 FullName

typeName
String

请求类型的完全限定名称,包括命名空间而不是程序集,由 FullName 属性返回。

ignoreCase
Boolean

一个布尔值,指定是否执行区分大小写的搜索。

bindingAttr
BindingFlags

影响搜索 typeName 构造函数的零个或多个位标志的组合。 如果 bindingAttr 为零,则会对公共构造函数执行区分大小写的搜索。

binder
Binder

一个对象,它允许绑定、强制参数类型、调用成员以及使用反射检索 MemberInfo 对象。 如果 binder 为 null,则使用默认绑定器。

args
Object[]

要传递给构造函数的参数。 此参数数组必须以数字、顺序和键入要调用的构造函数的参数匹配。 如果首选无参数构造函数,args 必须是空数组或 null。

culture
CultureInfo

一个特定于区域性的对象,用于控制类型的强制。 如果 culturenull,则使用当前线程的 CultureInfo

activationAttributes
Object[]

可以参与激活的一个或多个属性的数组。 通常,包含单个 UrlAttribute 对象的数组。 ,指定激活远程对象所需的 URL。

此参数与客户端激活的对象相关。 客户端激活是保留的旧技术,用于向后兼容,但不建议用于新开发。 分布式应用程序应改用 Windows Communication Foundation。

返回

typeName指定的对象的实例。

例外

assemblyNametypeNamenull

找不到匹配的构造函数。

assemblyName中找不到 typeName

找不到 assemblyName

调用方无权调用此构造函数。

调用方无法为不继承自 MarshalByRefObject的对象提供激活属性。

在卸载的应用程序域中尝试此操作。

assemblyName 当前加载的运行时不是有效的程序集。

程序集或模块加载了两次,其中包含两个不同的证据。

示例

下面的示例演示如何使用 ignoreCase 参数。

C#
using System;
using System.Reflection;

class IgnoreCaseSnippet {

   static void Main() {
      InstantiateINT32(false);     // Failed!
      InstantiateINT32(true);      // OK!
   }

   static void InstantiateINT32(bool ignoreCase) {
      try {
         AppDomain currentDomain = AppDomain.CurrentDomain;
         object instance = currentDomain.CreateInstanceAndUnwrap(
            "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
            "SYSTEM.INT32",
            ignoreCase,
            BindingFlags.Default,
            null,
            null,
            null,
            null,
            null
         );
         Console.WriteLine(instance.GetType());
      } catch (TypeLoadException e) {
         Console.WriteLine(e.Message);
      }
   }
}

注解

这是一种将 CreateInstanceObjectHandle.Unwrap相结合的便利方法。

有关 assemblyName格式,请参阅 AssemblyName。 有关 typeName格式,请参阅 Type.FullName 属性。

备注

如果对 CreateInstanceAndUnwrap返回的 T1 类型的对象的方法 M 进行早期绑定调用,并且该方法对程序集中类型 T2 对象的方法进行早期绑定调用,C 当前程序集或包含 T1的程序集,则程序集 C 将加载到当前应用程序域中。 即使对 T1.M() 的早期绑定调用是在 DynamicMethod的正文或其他动态生成的代码中进行的,也会发生此加载。 如果当前域是默认域,则在进程结束之前,无法卸载程序集 C。 如果当前域稍后尝试加载程序集 C,则加载可能会失败。

另请参阅

适用于

.NET 9 和其他版本
产品 版本
.NET Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1

CreateInstanceAndUnwrap(String, String, Boolean, BindingFlags, Binder, Object[], CultureInfo, Object[], Evidence)

注意

Methods which use evidence to sandbox are obsolete and will be removed in a future release of the .NET Framework. Please use an overload of CreateInstanceAndUnwrap which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.

创建指定类型的新实例。 参数指定类型的名称及其创建方式。

C#
public object CreateInstanceAndUnwrap (string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture, object[] activationAttributes, System.Security.Policy.Evidence securityAttributes);
C#
[System.Obsolete("Methods which use evidence to sandbox are obsolete and will be removed in a future release of the .NET Framework. Please use an overload of CreateInstanceAndUnwrap which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public object CreateInstanceAndUnwrap (string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture, object[] activationAttributes, System.Security.Policy.Evidence securityAttributes);

参数

assemblyName
String

程序集的显示名称。 请参阅 FullName

typeName
String

请求类型的完全限定名称,包括命名空间而不是程序集,由 FullName 属性返回。

ignoreCase
Boolean

一个布尔值,指定是否执行区分大小写的搜索。

bindingAttr
BindingFlags

影响搜索 typeName 构造函数的零个或多个位标志的组合。 如果 bindingAttr 为零,则会对公共构造函数执行区分大小写的搜索。

binder
Binder

一个对象,它允许绑定、强制参数类型、调用成员以及使用反射检索 MemberInfo 对象。 如果 binder 为 null,则使用默认绑定器。

args
Object[]

要传递给构造函数的参数。 此参数数组必须以数字、顺序和键入要调用的构造函数的参数匹配。 如果首选无参数构造函数,args 必须是空数组或 null。

culture
CultureInfo

一个特定于区域性的对象,用于控制类型的强制。 如果 culturenull,则使用当前线程的 CultureInfo

activationAttributes
Object[]

可以参与激活的一个或多个属性的数组。 通常,包含单个 UrlAttribute 对象的数组,该对象指定激活远程对象所需的 URL。

此参数与客户端激活的对象相关。 客户端激活是保留的旧技术,用于向后兼容,但不建议用于新开发。 分布式应用程序应改用 Windows Communication Foundation。

securityAttributes
Evidence

用于授权创建 typeName的信息。

返回

typeName指定的对象的实例。

属性

例外

assemblyNametypeNamenull

找不到匹配的构造函数。

assemblyName中找不到 typeName

找不到 assemblyName

调用方无权调用此构造函数。

调用方无法为不继承自 MarshalByRefObject的对象提供激活属性。

在卸载的应用程序域中尝试此操作。

assemblyName 当前加载的运行时不是有效的程序集。

程序集或模块加载了两次,其中包含两个不同的证据。

示例

下面的示例演示如何使用 ignoreCase 参数。

C#
using System;
using System.Reflection;

class IgnoreCaseSnippet {

   static void Main() {
      InstantiateINT32(false);     // Failed!
      InstantiateINT32(true);      // OK!
   }

   static void InstantiateINT32(bool ignoreCase) {
      try {
         AppDomain currentDomain = AppDomain.CurrentDomain;
         object instance = currentDomain.CreateInstanceAndUnwrap(
            "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
            "SYSTEM.INT32",
            ignoreCase,
            BindingFlags.Default,
            null,
            null,
            null,
            null,
            null
         );
         Console.WriteLine(instance.GetType());
      } catch (TypeLoadException e) {
         Console.WriteLine(e.Message);
      }
   }
}

注解

这是一种将 CreateInstanceObjectHandle.Unwrap相结合的便利方法。

有关 assemblyName格式,请参阅 AssemblyName。 有关 typeName格式,请参阅 Type.FullName 属性。

备注

如果对 CreateInstanceAndUnwrap返回的 T1 类型的对象的方法 M 进行早期绑定调用,并且该方法对程序集中类型 T2 对象的方法进行早期绑定调用,C 当前程序集或包含 T1的程序集,则程序集 C 将加载到当前应用程序域中。 即使对 T1.M() 的早期绑定调用是在 DynamicMethod的正文或其他动态生成的代码中进行的,也会发生此加载。 如果当前域是默认域,则在进程结束之前,无法卸载程序集 C。 如果当前域稍后尝试加载程序集 C,则加载可能会失败。

另请参阅

适用于

.NET Framework 4.8.1 和其他版本
产品 版本 (已过时)
.NET Framework 1.1, 2.0, 3.0, 3.5 (4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1)