我在当前正在编写的附件中使用未完全公开的API。尽管某些公共方法需要这些类型的参数,但其中的某些类仍保留在内部。
为解决该问题,我尝试将动态类型与帮助程序DymamicObject实现一起使用。我这样做非常成功,但是有一次我得到了RuntimeBinderException,它没有告诉我确切的细节: “对于Autodesk.Civil.DatabaseServices.PressurePipeNetwork.AddLinePipe(Autodesk.AutoCAD.Geometry.LineSegment3d,Autodesk.Civil.DatabaseServices.Styles.PressurePartSize)的最佳重载方法匹配具有一些无效的参数”。
在调试过程中,我可以看到我的动态变量属于预期类型,并且通常是有效对象-在其属性中包含预期信息。
如何解决该问题? 我如何检查此方法调用到底有什么问题?
在当前代码下方(AddLinePipe方法引发异常)
var network = (PressurePipeNetwork)tr.GetObject(networkId, OpenMode.ForWrite);
var pressurePartList = doc.Styles.GetPressurePartListsExt() as StyleCollectionBase;
var myListId = pressurePartList["My Parts"];
var myList = tr.GetObject(myListId, OpenMode.ForRead);
dynamic exposedPartsList = new ExposedPressureObject(myList);
dynamic myPipes = exposedPartsList.GetParts(PressurePartDomainType.Pipe);
dynamic myPipesExposed = new ExposedPressureObject(myPipes);
dynamic pipe = myPipesExposed[0];
LineSegment3d line = new LineSegment3d(new Point3d(30, 9, 0), new Point3d(33, 8, 0));
//here is the public method, requirng a variable of internal type
network.AddLinePipe(line, pipe);
以下DymamicObject的实现:
class ExposedPressureObject : DynamicObject
{
private object _object;
private IEnumerable<object> _listObject = new List<object>();
public ExposedPressureObject(object obj)
{
System.Collections.IEnumerable enumerable = obj as System.Collections.IEnumerable;
if (enumerable == null)
_object = obj;
else
_listObject = enumerable.Cast<object>();
}
public override bool TryInvokeMember(
InvokeMemberBinder binder, object[] args, out object result)
{
// Find the called method using reflection
var methodInfo = _object.GetType().GetMethod(
binder.Name,
new[] { args[0].GetType() });
// Call the method
result = methodInfo.Invoke(_object, args);
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
PropertyInfo propInfo = _object.GetType().GetProperty(binder.Name,
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
result = propInfo.GetValue(_object , null);
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
int index = (int)indexes[0];
result = _listObject.ToList()[index];
return true;
}
}