你不能卸载单个程序集 - 你必须卸载整个 AppDomain。换句话说,你需要在一个新的 AppDomain 中加载你的其他程序集(和相关代码),然后当你想要卸载它时,你卸载 AppDomain。 当然,这使得生活变得更加困难,因为你必须担心在 AppDomains 之间调用的封送调用 - 但这是 .NET 允许的唯一方式。
正如Jon Skeet所写,您无法卸载DLL,但可以在另一个AppDomain中加载DLL,然后卸载AppDomain。这是唯一的方法。然而,有些事情需要注意,因为您自然会跨AppDomain调用函数。这可以通过两种不同的方式发生。如果您从一个AppDomain(称为A)获取对在AppDomain B中实例化的对象的引用,则默认行为是该对象跨AppDomain边界进行序列化。这意味着A访问的对象实例与B访问的对象实例不同,并且在A中进行的修改不会反映在B中,除非您提供将对象发送回的功能。这要求对象标记为Serializable。但是,您可以通过让类继承MarshalByRefObject来避免序列化。如果在AppDomain B中构造了对象,并从AppDomain A中调用,则调用将跨越AppDomain边界。它仍将是相同的物理线程,因此您没有跨进程调用或COM跨公寓调用的线程切换开销。但是,如果您在B中构造了一个由A中的对象引用的对象,但B中的对象未被访问5分钟,那么该对象将被处理。可以在MarshalByRefObject.InitializeLifetimeService()中覆盖此行为。