CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  .NET技术 >  C#

反射问题,高手请进

楼主liyihui2001(辉)2006-09-25 09:39:54 在 .NET技术 / C# 提问

采用反射创建的对象无法进行类型转换,详细如下  
   
  一个基于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);  
                                  }  
                          }  
                  }  
   
  哪位能解决,分不够可以再加。  
  如果这种调用不行,该用哪种方式实现我的功能?? 问题点数:50、回复次数:35Top

1 楼fengfangfang()回复于 2006-09-25 09:57:20 得分 0

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);  
  }Top

2 楼fengfangfang()回复于 2006-09-25 09:58:00 得分 0

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

3 楼Knight94(愚翁)回复于 2006-09-25 12:07:58 得分 0

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

4 楼wl22817560()回复于 2006-09-25 12:20:40 得分 0

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

5 楼liyihui2001(辉)回复于 2006-09-25 13:49:13 得分 0

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

6 楼Knight94(愚翁)回复于 2006-09-25 13:59:03 得分 0

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

7 楼fengfangfang()回复于 2006-09-25 14:04:12 得分 0

ClassLibrary1.Class1的代码贴出来看看Top

8 楼fengfangfang()回复于 2006-09-25 14:06:41 得分 0

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

9 楼liyihui2001(辉)回复于 2006-09-25 14:08:00 得分 0

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

10 楼hdt(倦怠)回复于 2006-09-25 14:09:07 得分 0

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

11 楼liyihui2001(辉)回复于 2006-09-25 14:09:56 得分 0

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  
          }  
  }Top

12 楼Ivony(授人以鱼不如授人以渔,上海谋生)回复于 2006-09-25 14:12:51 得分 0

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

13 楼Ivony(授人以鱼不如授人以渔,上海谋生)回复于 2006-09-25 14:13:34 得分 5

类型名字相同,命名空间不一定相同,就算全名相同也不一定是同一个类型。Top

14 楼viena(维也纳N02)回复于 2006-09-25 14:14:18 得分 0

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

15 楼liyihui2001(辉)回复于 2006-09-25 14:16:34 得分 0

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

16 楼liyihui2001(辉)回复于 2006-09-25 14:22:12 得分 0

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

17 楼hdt(倦怠)回复于 2006-09-25 14:22:48 得分 5

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

18 楼Samen168(Code to coding)回复于 2006-09-25 14:22:52 得分 0

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

19 楼hdt(倦怠)回复于 2006-09-25 14:24:35 得分 0

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

20 楼liyihui2001(辉)回复于 2006-09-25 14:24:53 得分 0

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

21 楼Knight94(愚翁)回复于 2006-09-25 14:26:57 得分 0

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

22 楼fengfangfang()回复于 2006-09-25 14:32:10 得分 0

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

23 楼viena(维也纳N02)回复于 2006-09-25 14:33:53 得分 0

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

24 楼liyihui2001(辉)回复于 2006-09-25 14:36:09 得分 0

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

25 楼hdt(倦怠)回复于 2006-09-25 14:42:48 得分 0

跟踪一下  
  接口的  
  AssemblyQualifiedNameTop

26 楼liyihui2001(辉)回复于 2006-09-25 14:43:20 得分 0

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

27 楼liyihui2001(辉)回复于 2006-09-25 14:48:10 得分 0

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

28 楼hdt(倦怠)回复于 2006-09-25 14:55:26 得分 0

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

29 楼Knight94(愚翁)回复于 2006-09-25 15:06:37 得分 40

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

30 楼Knight94(愚翁)回复于 2006-09-25 15:10:24 得分 0

那么正确的调用方式应该如下:  
  //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()   );  
   
   
  Top

31 楼liyihui2001(辉)回复于 2006-09-25 15:12:34 得分 0

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

32 楼yzx110(原振侠)回复于 2006-09-25 16:04:24 得分 0

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

33 楼yzqlee()回复于 2006-09-25 16:18:06 得分 0

upTop

34 楼liyihui2001(辉)回复于 2006-09-25 17:42:46 得分 0

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

35 楼szh3210(/+/=〆)回复于 2006-09-26 10:14:00 得分 0

markTop

相关问题

关键词

得分解答快速导航

  • 帖主:liyihui2001
  • Ivony
  • hdt
  • Knight94

相关链接

  • CSDN .NET频道
  • .NET类图书
  • C#类图书
  • .NET类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo