采用反射创建的对象无法进行类型转换,详细如下一个基于WinForm的程序,为了扩展功能,实现我自己的接口,如下:
public partial class frmMain : Form,IMyApp

     .....
}
IMyApp里实现对frmMain的几个属性调用,如:
public interface IMyApp
    {
        string Caption
        {
            get;
            set;
        }        FormWindowState WindowState
        {
            get;
            set;
        }        Size WindowSize
        {
            get;
            set;
        }        StatusStrip StatusBar
        {
            get;
        }        MenuStrip Menus
        {
            get;
        }    }同时又写了个IPlugIn接口,如下:
public interface IPlugIn : IDisposable
    {
        void Initialize(IGISApp app);
    }另外建立一个类工程,写了一个从IPlugIn 派生的类,编译为Dll,放在WinForm目录下面,通过下面语句动态加载,创建类的实例,但是,提示类型不能转换:
LoadPlugs在Form的Load事件里调用private void LoadPlugs()
        {
            string fileName = Application.StartupPath + "\\ClassLibrary1.dll";
            Assembly asm = Assembly.LoadFile(fileName);
            Type[] types = asm.GetTypes();
            foreach (Type type in types)
            {
                if (type.GetInterface("IPlugIn") != null)
                {
                    Object obj = Activator.CreateInstance(type);
                    IPlugIn plug = (IPlugIn)obj; //这里出错,提示为'无法将类型为“ClassLibrary1.Class1”的对象强制转换为类型“MyAPP.Interface.IPlugIn”'
                    plug.Initialize(this);
                }
            }
        }哪位能解决,分不够可以再加。
如果这种调用不行,该用哪种方式实现我的功能??

解决方案 »

  1.   

    private static IPetShopCacheDependency LoadInstance(string className) {    string path = ConfigurationManager.AppSettings["CacheDependencyAssembly"];
        string fullyQualifiedClass = path + "." + className;    // Using the evidence given in the config file load the appropriate assembly and class
        return (IPetShopCacheDependency)Assembly.Load(path).CreateInstance(fullyQualifiedClass);
    }
      

  2.   

    PetShop4.0中的应用http://blog.csdn.net/fengfangfang/archive/2006/09/06/1185077.aspx
      

  3.   

    yun~接口对象不能直接实例化,需要通过实现接口的类型对象进行转换。
    也就是说需要通过实现IPlugIn接口类型去转换得到IPlugIn对象。目前从你的说明来说,好像并没有对IPlugIn并没有进行实现。
      

  4.   

    http://community.csdn.net/Expert/topic/5045/5045049.xml?temp=.7106897
    借点人气 找人帮帮忙
      

  5.   

    Knight94(愚翁) :
    是不是没有看清楚我写的?我从IPlugIn派生了一个类,实现了IPlugIn的接口,编译成一个Dll了,怎么说没有对IPlugIn进行实现呢?
      

  6.   

    to 是不是没有看清楚我写的?我从IPlugIn派生了一个类,实现了IPlugIn的接口,编译成一个Dll了,怎么说没有对IPlugIn进行实现呢?Sorry!那么不能直接通过createinstance创建IPlugIn接口对象,需要通过用其派生的类型产生对象,然后转化成IPlugIn接口对象。
      

  7.   

    ClassLibrary1.Class1的代码贴出来看看
      

  8.   

    使用Assembly.Load方法和Assembly.CreateInstance,不要使用Activator.CreateInstance
      

  9.   

    我跟了一下,在循环中得到的types中的IPlugIn接口已经通过type.GetInterface("IPlugIn") != null 过滤掉了,确实不是实例化IPlugIn接口的,创建成功的是ClassLibrary1.Class1的对象,可为啥就是不能转换成接口呢?创建的对象都是正确的,就是转换不让转,快帮帮我吧
      

  10.   

    Object obj = Activator.CreateInstance(type);
                        IPlugIn plug = (IPlugIn)obj; //这里出错,提示为'无法将类型为“ClassLibrary1.Class1”的
    ===================
    obj is object is can't converttry
    Object obj = Activator.CreateInstance(type);
                        IPlugIn plug = obj as IPlugIn;
      

  11.   

    Class1的代码如下:using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    namespace ClassLibrary1
    {
        public class Class1 : SharpMapClient.Interface.IPlugIn
        {
            #region IPlugIn 成员        public void Initialize(SharpMapClient.IGISApp app)
            {
                MenuStrip ms = app.Menus;
                ToolStripMenuItem item = ms.Items[1] as ToolStripMenuItem;
                item.DropDownItems.Add("AAAA");
            }        #endregion        #region IDisposable 成员        public void Dispose()
            {
                throw new Exception("The method or operation is not implemented.");
            }        #endregion
        }
    }
      

  12.   

    type.GetInterface(typeof(IPlugIn).Name) == typeof( IPlugIn ) !!!
      

  13.   

    //if (type.GetInterface("IPlugIn") != null)
    这样得到的未必是实现此接口的类
    也可能是继承此接口的接口,此时直接创建实例肯定会出错
      

  14.   

    fengfangfang() :
    Assembly.CreateInstance和Activator.CreateInstance结果是一样的,创建的对象都是正确的,转换时就报“InvalidCastException"异常。
      

  15.   

    hdt(倦怠) :
    用as转换早就试过,这种方法不报异常,就是转换后为null了。
      

  16.   

    IPlugIn 单独做个组件dll,其他工程同时引用同一个IPlugIn,怀疑是你们引用的是不同IPlugIn
      

  17.   

    IPlugIn plug = (IPlugIn)obj; //这里出错,提示为'无法将类型为“ClassLibrary1.Class1”的对象强制转换为类型“MyAPP.Interface.IPlugIn”'SharpMapClient.Interface.IPlugIn这是同名的两个不同接口
      

  18.   

    IPlugIn最好用强名称控制,否则易出现dll hole问题。
      

  19.   

    Ivony()和viena(维也纳nn):
    创建的对象是正确的,肯定是一个类型,这点能保证,我在Class1里加了个属性,创建的对象里都能跟进去看到这个属性的值。
      

  20.   

    正如“Samen168(技术==>价值) ”所说,两者不是同一个类型
      

  21.   

    “MyAPP.Interface.IPlugIn”'SharpMapClient.Interface.IPlugIn确实是两个接口
      

  22.   

    //IPlugIn plug = (IPlugIn)obj; 
    把鼠标指针放到IPlugIn上看一下它的Namspace对不对
      

  23.   

    不好意思,给大家说明,写的时候为了省略,就写成了MyAPP.Interface.IPlugIn,两者都是SharpMapClient.Interface.IPlugIn,我添加的是同一个文件,命名空间我都改成一样的了,怎么修改都是这个错误,两个工程里的接口文件一模一样的。大家先不要怀疑对象不正确,创建成功后,看到一切的是正确的,就是不能转换。
      

  24.   

    跟踪一下
    接口的
    AssemblyQualifiedName
      

  25.   

    我用的是VS2005,哪位有时间随便写个接口,写个类,编译成Dll,在另外一个程序中调用一下,应该也是这个问题。
      

  26.   

    type信息如下:
    AssemblyQualifiedName = "SharpMapClient.Interface.Class1, ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"SharpMapClient.Interface.IPlugIn plug = (SharpMapClient.Interface.IPlugIn)obj;就错了
      

  27.   

    把你的项目设置详细说说,我怀疑
    是你引用了 SharpMapClient.Interface 这个dll,再用Assembly.load 这个dll,出现的问题
      

  28.   

    to 不好意思,给大家说明,写的时候为了省略,就写成了MyAPP.Interface.IPlugIn,两者都是 SharpMapClient.Interface.IPlugIn,我添加的是同一个文件,命名空间我都改成一样的了,怎么修改都是这个错误,两个工程里的接口文件一模一样的。即使定义完全一样,都是通过同一个文件产生的,但是在不同项目中编译后,就属于不同的类型。
      

  29.   

    那么正确的调用方式应该如下:
    //dll file
    using System;namespace InterfaceTest
    {
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    public class clsTest:IDisplayName
    {
    public clsTest()
    {
    //
    // TODO: Add constructor logic here
    //
    }
    #region IDisplayName Members public string GetName()
    {
    // TODO:  Add clsTest.GetName implementation
    return "hello world";
    } #endregion
    } public interface IDisplayName
    {
    string GetName();
    }
    }//程序中调用如下:
    Assembly ass = Assembly.LoadFile( yourDllFile );
    Type typClass = ass.GetType( "InterfaceTest.clsTest" );
    object obj = typClass.InvokeMember( 
    null,
    BindingFlags.DeclaredOnly |
    BindingFlags.Public | BindingFlags.NonPublic |
    BindingFlags.Instance | BindingFlags.CreateInstance,
    null,
    null,
    null );
    Type typInterface = typClass.GetInterface( "InterfaceTest.IDisplayName" );MethodInfo mi = typInterface.GetMethod( "GetName" );
    if( mi != null )
    Debug.WriteLine( mi.Invoke( obj, null ).ToString() );
      

  30.   

    多谢Knight94(愚翁),Knight94(愚翁)的解释是正确的。现在我把两个项目里面的接口文件都删除掉,重新建立了一个工程,把两个接口文件都加进去,编译成接口只包含两个接口的Dll,我的程序工程和接口类工程都对这个Dll进行引用,转换没有问题。即使定义完全一样,都是通过同一个文件产生的,但是在不同项目中编译后,就属于不同的类型。(这句最重要,呵呵)再次多谢各位。
      

  31.   

    lz的代码算是一个繁琐的做法你直接配置实现了IPlugIn借口的类型
    比如type="ClassLibrary.Class1, ClassLibrary";代码中调用 Type t = Type.GetType(type);if ( t == null) // process the exception
    然后 IPlugIn p = (IPlugIn)Activator.CreateInstance(t);
      

  32.   

    呵呵,从IPlugIn派生的类我可不知道,谁都可以写个类,只要放到指定的地方,我程序运行时才加载的,何来类名字?
    麻烦也只能这样了。