C#-IsAssignableFrom(甚至ImplementInterface)如何工作

我在C#中有一个来自*的插件系统.
关键部分是Assembly.LoadFile,Type.IsAssignableFrom和Activator.CreateInstance.它有效,但是我不完全了解IsAssignableFrom如何识别外部程序集加载的类型.
说,我有

public interface PluginInterface 
{
    int calculateSomething();
}

我已经将其编译为PluginInterface.dll.

PluginInterface.dll是示例插件中的引用,例如:

public class CalculateOnePlugin : PluginInterface
{
    public int calculateSomething() { return 1; }
}

它被编译为CalculateOnePlugin.dll.

现在,创建一个引用PluginInterface.dll的应用程序,并尝试加载和使用CalculateOnePlugin.dll:

var pluginAssembly = Assembly.LoadFile("CalculateOnePlugin.dll");
Type interfaceType = typeof(PluginInterface);
Type[] typesInLoadedAssembly = pluginAssembly.GetTypes();
Type pluginType = null;
foreach (var typeInLoadedAssembly in typesInLoadedAssembly)
    if (interfaceType.IsAssignableFrom(typeInLoadedAssembly)) // ???
    {
        pluginType = typeInLoadedAssembly;
        break;
    }
if (pluginType!=null) 
{
    PluginInterface pi = (PluginInterface)Activator.CreateInstance(pluginType);
    // and do what you want with that plugin object
}

我的问题是IsAssignableFrom如何识别和匹配从两个外部程序集加载的类型? IsAssignableFrom考虑哪些程序集或类属性?

如果我复制PluginInterface的源代码并将其编译为(例如)AnotherPluginInterface.dll,并在构建CalculateOnePlugin.dll时使用此引用,则它将无法正常工作.因此,类型匹配不仅在乎方法签名,例如,它以某种方式知道程序集和类型的来源.

当我为应用程序和插件使用两种不同版本的PluginInterface时(即在后者中添加了一个方法),它将无法再次使用,因此这两个dll的来源还不够,它内部必须包含某些版本的东西它.

但是,只需在两种用法(应用程序和插件)之间重新编译PluginInterface不会使事情变得混乱,它可以工作.

PluginInterface.dll的GUID是否包含在CalculateOnePlugin.dll的引用中,这是IsAssignableFrom知道它们相同的方式吗?还是将类似哈希的值用于类型?还是两者都?

解决方法:

My question is how IsAssignableFrom identifies and matches the types loaded from two external assembly? What assembly or class properties are taken into consideration by IsAssignableFrom?

本质上进行了等效比较.

类型派生自称为RunTimeType的类.

RunTimeType有一个Equality运算符,它执行如下检查:

 return RuntimeTypeHandle.IsEquivalentTo(this, otherRtType);

不幸的是RuntimeTypeHandle.IsEquivalentTo被标记为CLR核心的一部分,无法反映出来,因此我无法确切告诉您它的外观或代码中的功能.

但是,根据this article entitled “Anatomy of a .NET Assembly”,

Type values are stored using a string representing the type name and fully qualified assembly name (for example, MyNs.MyType, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0123456789abcdef). If the type is in the current assembly or mscorlib then just the type name can be used.

因此,程序集名称,区域性,版本,名称空间和公共密钥令牌似乎都可以匹配,以便唯一地标识类型.

上一篇:java-如何安全地更改变量intellij的类型?


下一篇:tensorflow InvalidArgumentError:您必须使用dtype float输入占位符张量的值