使用Activator.CreateInstance的奇怪行为

时间:2009-10-17 01:08:33

标签: c# .net

假设我在类库中定义了以下类层次结构:

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
    }

我在控制台应用程序中使用这个程序集并使用反射我正在创建一个类型为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();

以上工作正常。 现在,如果我使用此代码并将其移植到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在以下行中为null:

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

有趣的是,当我调试网页时,我在'typeDef'变量中有一个有效的类型定义,如果我添加Activator.CreateInstance(typeDef) as IFoo,有什么奇怪的 在Visual Studio的Watch窗口中,结果不为null!

我在这里缺少什么?

P.S。 - 我已经验证了程序集(TestClassLib.dll)存在于ASP.NET应用程序的bin目录中。

2 个答案:

答案 0 :(得分:1)

我的猜测是你从Activator.CreateInstance中获取对象,但是防御性强制转换(“as IFoo”)失败,可能是由于加载上下文(因为你使用LoadFrom加载了程序集 - 请参阅{{3 }})。是否在调用程序集和动态加载的程序集中定义了IFoo perchance?也许尝试让Fusion通过使用程序集限定类型名称的Type.GetType()来加载程序集,看看你是否得到相同的结果(也尝试存储在没有“as”的对象ref中,以确保CreateInstance给你某事返回)。

答案 1 :(得分:-1)

据我所知,当您要转换的类/类型具有构造函数时,您只能使用as。显然,接口没有构造函数。因此,您必须以正常样式打包:

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

我很确定是这种情况,但我可能错了。