简体   繁体   English

使用Activator.CreateInstance的怪异行为

[英]Weird behavior using Activator.CreateInstance

Say I have the following class hierarchy defined in a class library: 假设我在类库中定义了以下类层次结构:

public interface IFoo
    {
        string GetMsg();
    }

    public abstract class FooBase
    {
        public virtual string GetMsg()
        {
            return "Foobase msg";
        }
    }

    public class Foo : FooBase, IFoo
    {

        #region IFoo Members

        public new string GetMsg()
        {
            return base.GetMsg();
        }

        #endregion
    }

I'm consuming this assembly in a console application and using reflection I'm creating an instance of the Foo class typed to IFoo as follows: 我在控制台应用程序中使用了该程序集,并使用反射创建了输入为IFoo的Foo类的实例,如下所示:

 Assembly a = Assembly.LoadFile(Path.GetFullPath("TestClassLib.dll"));
 var typeDef =  a.GetType("TestClassLib.Foo");
 var fooInst = Activator.CreateInstance(typeDef) as IFoo;
 string msg = fooInst.GetMsg();

The above works fine. 以上工作正常。 Now if I take this code and port it to an ASP.NET Web web page like so: 现在,如果我采用以下代码并将其移植到ASP.NET Web网页上,如下所示:

namespace TestWebApp
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string filePath = Server.MapPath(@"~/bin/TestClassLib.dll");
            Assembly a = Assembly.LoadFile(Path.GetFullPath(filePath));
            var typeDef = a.GetType("TestClassLib.Foo");
            var fooInst = Activator.CreateInstance(typeDef) as IFoo;
            string msg = fooInst.GetMsg();
        }
    }
}

fooInst is null on the following line: fooInst在以下行中为null:

var fooInst = Activator.CreateInstance(typeDef) as IFoo;

What's interesting is when I debug the web page, I have a valid type definition in 'typeDef' variable and what is weird is that if I add Activator.CreateInstance(typeDef) as IFoo to the Watch window in Visual Studio the result is not null! 有趣的是,当我调试网页时,在'typeDef'变量中有一个有效的类型定义,而且很奇怪的是,如果我将Activator.CreateInstance(typeDef) as IFoo到Visual Studio的“监视”窗口中,则结果不为null。 !

What am I missing here? 我在这里想念什么?

PS - I've already verified that the assembly(TestClassLib.dll) is present in the bin directory of the ASP.NET app. PS-我已经验证了Assembly(TestClassLib.dll)是否存在于ASP.NET应用程序的bin目录中。

My guess is that you're getting the object back from Activator.CreateInstance, but the defensive cast ("as IFoo") is failing, possibly due to load context (since you loaded the assembly with LoadFrom- see here ). 我的猜测是,您是从Activator.CreateInstance取回对象的,但是防御性的强制转换(“作为IFoo”)失败了,这可能是由于加载上下文(因为使用LoadFrom加载了程序集,请参见此处 )。 Is IFoo perchance defined in both the calling assembly and the one you're loading dynamically? 是否在调用程序集和要动态加载的程序集中都定义了IFoo性能? Maybe try letting Fusion load the assembly by doing a Type.GetType() with an assembly-qualified type name to see if you get the same result (also try storing in an object ref without the "as" to make sure CreateInstance is giving you something back). 也许尝试通过使用具有程序集限定类型名称的Type.GetType()来让Fusion加载程序集,以查看是否得到相同的结果(也可以尝试将存储在对象引用中而不带“ as”,以确保CreateInstance给您)回来的东西 )。

As far as I know, you can only use as when the class/type you are casting to has a constructor. 据我所知,你只能使用as上课的时候/类型你是铸造有一个构造函数。 Obviously, an interface does not have a constructor. 显然,接口没有构造函数。 Therefore, you must box in the normal style: 因此,您必须使用常规样式进行装箱:

var fooInst = (IFoo)Activator.CreateInstance(typeDef);

I'm pretty sure this is the case, but I could be wrong. 我很确定是这种情况,但是我可能是错的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM