我有一个有趣的案例,我和我的同事都无法理解。我们已经在.NET C#中为第三方软件(Autodesk Revit 2018)开发了一个插件。我们的插件和宿主应用程序(Revit)都使用名为 Xceed.AvalonDock.dll 的程序集,但版本不同。我们的插件使用版本 3.2.0 ,Revit使用 2.0.0 。
对某些客户'机器启动我们的应用程序由于以下 TypeLoadException :
而失败System.TypeLoadException
GenericArguments[0], 'Xceed.Wpf.AvalonDock.Layout.ILayoutPanelElement', on 'Xceed.Wpf.AvalonDock.Layout.LayoutGroup`1[T]' violates the constraint of type parameter 'T'.
at System.RuntimeTypeHandle.Instantiate(RuntimeTypeHandle handle, IntPtr* pInst, Int32 numGenericArgs, ObjectHandleOnStack type)
at System.RuntimeTypeHandle.Instantiate(Type[] inst)
at System.RuntimeType.MakeGenericType(Type[] instantiation)
我们的项目引用了Xceed(从我们的.vcsproj文件中复制):
<Reference Include="Xceed.Wpf.AvalonDock, Version=3.2.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\..\..\..\packages\Extended.Wpf.Toolkit.3.2.0\lib\net40\Xceed.Wpf.AvalonDock.dll</HintPath>
<Private>True</Private>
</Reference>
显然,我们指定了确切的DLL版本(甚至是公钥令牌)。我已经在我的机器上进行了测试,即使Revit加载了dll的2.0版本(它需要),我们的插件也会在启动时加载3.2版本。
让我感到困惑的是,异常的错误消息似乎是错误的。为什么?看看LayoutGroup&lt;&gt;:
的声明[Serializable]
public abstract class LayoutGroup<T> : LayoutGroupBase ... where T : class, ILayoutElement
该消息指出ILayoutPanelElement不满足where子句。它是ILayoutElement的子类型,它的所有子类型都是引用类型(即使它们是结构体,我相信自动装箱会照顾它)。显然它确实满足where子句,不是吗?
什么可能导致这种例外?消息是红鲱鱼吗?可能是在客户端的计算机上,DLL版本混淆了吗?如果是这样,为什么它不在我们的机器上。我已经在Windows 7和10上进行了测试,但无法重现此异常。
如果有人有想法,请帮忙!
更新: AvalonDock是开源的。我已经检查了LayoutGroup,ILayoutElement和ILayoutPanelElement的声明的两个版本(版本2.0和3.2),并且异常消息对我来说似乎仍然是错误的。这部分代码没有太大变化。