【发布时间】:2019-01-10 11:04:15
【问题描述】:
我遇到了一种奇怪的情况,即以特定方式在 C# 字典上使用 getter 会产生参数异常,即使这应该 never happen。这个问题似乎只发生在我的电脑上。
实际上,我已经找到了解决原始问题的替代解决方案。但是我真的很想不明白为什么原来的解决方案不起作用。
我有用于 Solidworks 插件的字典。它跟踪打开的文档及其事件处理程序。它是这样定义的:
private Dictionary<ModelDoc2, DocumentEventHandler> _openDocs = new Dictionary<ModelDoc2, DocumentEventHandler>();
Solidworks 有method 来检索活动文档。当我尝试使用它来检索活动文档的事件处理程序时,如下所示:
_openDocs[SwApp.ActiveDoc]
我得到这个 ArgumentException:
System.ArgumentException: 'Method 'SWAddIn.DocumentEventHandler
get_Item(SolidWorks.Interop.sldworks.ModelDoc2)' declared on type
'System.Collections.Generic.Dictionary`2[SolidWorks.Interop.sldworks.ModelDoc2,SWAddIn.DocumentEventHandler]' cannot be called with instance of type
'System.Collections.Generic.Dictionary`2[SolidWorks.Interop.sldworks.ModelDoc2,SWAddIn.DocumentEventHandler]''
我发现的替代解决方案是先简单地将活动文档绑定到一个变量,如下所示:
ModelDoc2 activedoc = SwApp.ActiveDoc;
_openDocs[activedoc]
如果有人能帮助我理解那就太好了!
一些额外的信息:
根据文档,“ActiveDoc”应该返回一个“对象”,但智能感知告诉我这是一个动态的
如前所述,它只发生在我的机器上,所以我猜它在某种程度上是环境问题
sn-p 不起作用的代码直接来自 Solidworks 的示例文件。
ModelDoc2 在名为 SolidWorks.Interop.sldworks 的装配体中定义:
[CoClass(typeof(ModelDoc2Class))]
[Guid("B90793FB-EF3D-4B80-A5C4-99959CDB6CEB")]
public interface ModelDoc2 : IModelDoc2
如果感兴趣的话,这里是来自 excpetion 的堆栈跟踪:
at System.Linq.Expressions.Expression.ValidateCallInstanceType(Type instanceType, MethodInfo method)
at System.Linq.Expressions.Expression.ValidateAccessor(Expression instance, MethodInfo method, ParameterInfo[] indexes, ReadOnlyCollection`1& arguments)
at System.Linq.Expressions.Expression.ValidateIndexedProperty(Expression instance, PropertyInfo property, ReadOnlyCollection`1& argList)
at System.Linq.Expressions.Expression.Property(Expression instance, PropertyInfo indexer, IEnumerable`1 arguments)
at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.GenerateProperty(EXPRCALL pExpr)
at Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Visit(EXPR pExpr)
at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.GenerateLambda(EXPRCALL pExpr)
at Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Visit(EXPR pExpr)
at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.Rewrite(TypeManager typeManager, EXPR pExpr, IEnumerable`1 listOfParameters)
at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.CreateExpressionTreeFromResult(IEnumerable`1 parameters, ArgumentObject[] arguments, Scope pScope, EXPR pResult)
at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.BindCore(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding)
at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding)
at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable`1 args, IEnumerable`1 arginfos, DynamicMetaObject onBindingError)
at Microsoft.CSharp.RuntimeBinder.CSharpGetIndexBinder.FallbackGetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion)
at System.Dynamic.DynamicMetaObject.BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)
at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection`1 parameters, LabelTarget returnLabel)
at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site, Object[] args)
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at CortimeSWAddIn.SwAddin.OnPostDocChange() in C:\Users\asdf\Development\SWAdd\SWAddIn\SWAddIn\SwAddin.cs:line 1065
【问题讨论】:
-
这是出乎意料的。如果正确实现 COM 对象,它应该可以工作。您遇到的错误很奇怪,它告诉我们您为该方法提供了一个
System.Collections.Generic.Dictionary`2[SolidWorks.Interop.sldworks.ModelDoc2,SWAddIn.DocumentEventHandler]的实例。您确定您向我们展示的代码是有错误的真实代码吗? (我没有要测试的软件) -
相当肯定。还能在哪里?发生异常的整行代码是检查文档是否已完成加载:
if(_openDocs[SwApp.ActiveDoc].Loaded)。System.Collections.Generic.Dictionary`2[SolidWorks.Interop.sldworks.ModelDoc2,SWAddIn.DocumentEventHandler]是字典的类型。我的猜测是此错误消息是由于该方法被实现为扩展。并因此将其作为第一个参数(如果这有意义的话)。 -
这个异常很奇怪,因为类型相同。你在说什么扩展方法?我们能有真正的代码吗?
-
if(_openDocs[SwApp.ActiveDoc].Loaded)是真正的代码。也没有太多的上下文。在它之前唯一要做的就是检查活动文档是否为空
标签: c# linq dynamic clr solidworks