(即使您不了解Autocad,如果您了解动态C#对象,也可以提供帮助)
我尝试使用.NET(C#)创建一个Autocad命令,允许用户选择实体,并从这些实体中总计它们的长度。
选择部分没问题,我能够以
的形式获得所选元素的列表但是AcadEntity的许多子类型都有length属性。 (例如:AcadLine,AcadLWPolyline等) - 我不想在编译时知道所有这些类型是什么,我不能相信普通的Autocad用户只能使用其中一种或两种类型。
所以,我必须检查这些对象是否包含属性"长度"并获得该价值。
显然我可以尝试一下:
dynamic dynaEntity = (dynamic)AcadEntityInstance
try
{
double len = dynaEntity.Length;
LengthsPerType.AddOrSum(entityType, len);//personal method, no problem here
//entityType is a string found in AcadEntityInstance.ObjectName
//it returns an "AcDbLine", for instance, which is not an actual System.Type.
//The related Type is "AcadLine" - I can, for instance do (AcadLine)AcadEntityInstance
}
catch (System.Exception E) { }
但是如您所知,创建大量异常实际上并不是编程事物的最佳方式。所以,我需要一个干净的解决方案。
我尝试了什么?
通过反思获取属性:
PropertyInfo prop = dynaEntity.GetType().GetProperty("Length");
PropertyInfo prop = AcadEntityInstance.GetType().GetProperty("Length");
PropertyInfo prop = ((object)AcadEntityInstance).GetType().GetProperty("Length");
所有这些总是返回" null"
观察给定的对象,他们是" System .__ ComObject"。 "长度"属性(如果可用)出现在"展开动态视图"。
中的调试器中此代码有效,但仅限于"长度"。有没有办法在调用最后一行之前验证它?
var ArgInfo = Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(0, null);
var getMember = Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, "Length", dynaEntity.GetType(), new[] { ArgInfo });
var site = System.Runtime.CompilerServices.CallSite<Func<System.Runtime.CompilerServices.CallSite, object, object>>.Create(getMember);
var result = site.Target(site, dynaEntity);
我认为什么是好的解决方案?
到目前为止,我发现: