场景如下-
- 我有一个程序集,上面写着"MyAssembly"。此程序集中定义了一个接口,例如"IMyInterface"
- 在同一个程序集中,我有一个类(MyClass),其中有一个方法定义为:
public void MyMethod(IMyInterface对象){}
- 现在,在我的项目中,我创建了一个接口,其名称和属性与"MyAssembly"中的接口"IMyInterface"公开的名称和属性相同
- 我有一个扩展这个接口的类(我在项目中创建的接口),我想使用反射将该类的对象作为参数传递给不同程序集中的方法"MyMethod"
问题是-
- 当我尝试使用反射调用该方法时,我得到了"无法将对象转换为类型IMyInterface"的异常
代码-
Assembly myAssembly = Assembly.LoadFrom("MyAssembly");
object classObject = myAssembly.CreateInstance("MyClass");
Type classType = myAssembly.GetType("MyClass");
MethodInfo myMethod = classType.GetMethod("MyMethod", BindingFlags.Instance);
// Creating an object of class in the latest assembly and need to pass this
// to method in assembly with different version.
ClassExtendingMyInterface obj= new ClassExtendingMyInterface ();
myMethod.Invoke(classObject, new object[] { obj});
如果我说得对,那是因为创建的对象在不同的程序集中,而该方法所需的参数是它自己的程序集。
我想到的另一种方法是在类中创建我自己的动态方法,它将接受我的类的对象。
我曾尝试在谷歌上搜索并通过Reflection.Emit或RunSharp来动态创建您自己的类。但是,我们只能在动态生成的程序集中使用它,但不能在现有程序集中创建动态方法或类。
我知道在运行时生成程序集不是一个好方法。但我现在想不出什么了。谢谢你的帮助。
您正在与一种名为"类型标识"的东西作斗争,这是.NET框架中一个非常重要的DLL地狱计数器。类型不仅通过其命名空间名称和类型名称来标识,还包括它所来自的程序集的属性。特别是程序集显示名称,[AssemblyVersion]、[AssemblyCulture]、PublicKeyToken和(间接)ProcessorArchitecture。您可以使用type.AssemblyQualifiedName属性查看"real"类型名称。例如,System.String类是System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
这将阻止您在另一个程序集中伪造类型,除非您可以为该程序集提供完全相同的属性。更容易的是简单地使用现有的程序集,在您的情况下应该没有问题,因为您只使用了一个接口。
值得注意的是,这一要求在.NET4中有所放宽。如果名称和[Guid]匹配,则从COM类型库自动生成的类型是等效的。这有助于消除PIA并实现"嵌入互操作类型"功能。没有什么适用于你的情况。
此处:
现在,在我的项目中,我创建了一个接口,其名称和属性与"MyAssembly"中的接口"IMyInterface"公开的名称和属性相同。
存在问题;仅仅声明一个类似名称的接口是不够的。类型的作用域由其程序集确定;也就是说,对于CLR来说,是一个完全不同的接口。
相反,将引用添加到原始程序集,并实现已定义的接口。它只能定义一次。
如果我正确理解您的问题,我相信您希望在自己的程序集中定义接口,然后从其他两个程序集中引用通用接口程序集。这样,每个程序集都引用SAME接口定义:
创建并构建MyInterfaces dll:
namespace MyInterfaces
{
public interface IMyInterface
{
void SharedMethod();
}
}
然后在另一个项目中创建第一个程序集,并设置对为MyInterfaces创建的dll的引用。创建您的类,注意模块顶部的"using"语句:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyInterfaces;
namespace MyFirstProject
{
public class MyClass1
{
public void MyMethod(IMyInterface SomeObject) { }
}
}
现在,我相信您的动态对象创建应该可以工作,因为这两个对象实现了在"MyInterfaces"中定义的相同接口。