采用反射创建的对象无法进行类型转换,详细如下一个基于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);
}
}
}哪位能解决,分不够可以再加。
如果这种调用不行,该用哪种方式实现我的功能??
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);
}
}
}哪位能解决,分不够可以再加。
如果这种调用不行,该用哪种方式实现我的功能??
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);
}
也就是说需要通过实现IPlugIn接口类型去转换得到IPlugIn对象。目前从你的说明来说,好像并没有对IPlugIn并没有进行实现。
借点人气 找人帮帮忙
是不是没有看清楚我写的?我从IPlugIn派生了一个类,实现了IPlugIn的接口,编译成一个Dll了,怎么说没有对IPlugIn进行实现呢?
IPlugIn plug = (IPlugIn)obj; //这里出错,提示为'无法将类型为“ClassLibrary1.Class1”的
===================
obj is object is can't converttry
Object obj = Activator.CreateInstance(type);
IPlugIn plug = obj as IPlugIn;
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
}
}
这样得到的未必是实现此接口的类
也可能是继承此接口的接口,此时直接创建实例肯定会出错
Assembly.CreateInstance和Activator.CreateInstance结果是一样的,创建的对象都是正确的,转换时就报“InvalidCastException"异常。
用as转换早就试过,这种方法不报异常,就是转换后为null了。
创建的对象是正确的,肯定是一个类型,这点能保证,我在Class1里加了个属性,创建的对象里都能跟进去看到这个属性的值。
把鼠标指针放到IPlugIn上看一下它的Namspace对不对
接口的
AssemblyQualifiedName
AssemblyQualifiedName = "SharpMapClient.Interface.Class1, ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"SharpMapClient.Interface.IPlugIn plug = (SharpMapClient.Interface.IPlugIn)obj;就错了
是你引用了 SharpMapClient.Interface 这个dll,再用Assembly.load 这个dll,出现的问题
//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() );
比如type="ClassLibrary.Class1, ClassLibrary";代码中调用 Type t = Type.GetType(type);if ( t == null) // process the exception
然后 IPlugIn p = (IPlugIn)Activator.CreateInstance(t);
麻烦也只能这样了。