By Augusto Goncalves
On each new version, Civil 3D includes more and more .NET coverage, but a few features still missing or maybe not available on older versions. This article how go from COM to .NET and back.
Every time any Aecc-object is used, the code will require COM objects to be loaded. A common practice is to add reference to those objects (either from COM registered objects prior 2012 or from Interop namespaces on 2013), but that makes the plug-in version dependent. One alternative is to use Late-binding, where no COM reference is added, so the code is binary version independent, but the bad side is that we have no ‘auto-complete’ feature while writing code. If the project have references, declare objects As Aecc-something, like on the sample below, otherwise declare them As Object (late binding).
Several Civil 3D .NET objects have an AcadObject property, which will return the equivalent COM object type. One small consideration is to use TryCast (VB.NET) or the as operation (C#), instead of making the direct cast, which can avoid some casting problems when you are not sure about the conversion.
'the .NET Corridor object
Dim oCorridor As Autodesk.Civil.Roadway.DatabaseServices.Corridor
'...
'initialize the .NET corridor object somehow...
'...
'now let's cast to COM
'first create the COM Corridor object
Dim oAeccCorridor As Autodesk.AECC.Interop.Roadway.AeccCorridor
'second try cast, which will return Nothing case it is impossible
oAeccCorridor = TryCast(oCorridor.AcadObject, AeccCorridor)
'cast succeeded?
If (oAeccCorridor Is Nothing) Then
'yes! it is valid!
'do something here
End If
Now, how do we cast from COM to .NET? The AcadObject property is read-only and there is no property available to cast to the .NET equivalent of the same object. One solution is to open the object using the ObjectId from the COM object. The following code shows the typical, basic coding for accessing an object for read, in this case a Corridor object.
'the COM Corridor object
Dim oAeccCorridor As Autodesk.AECC.Interop.Roadway.AeccCorridor
'...
'initialize the COM corridor object somehow...
'...
'get the .NET Database object
Dim db As Database = Autodesk.AutoCAD.ApplicationServices. _
ApplicationDocumentManager.MdiActiveDocument.Database
'start a transation with "using" keyword
Using trans As Transaction = db.TransactionManager.StartTransaction
'create the .NET corridor object
Dim oCorridor As Autodesk.Civil.Roadway.DatabaseServices.Corridor
'open it using the transaction, for READ or for WRITE
'like from COM to .NET, try cast before use it
Dim corridorId As ObjectId = New ObjectId(New IntPtr( _
oAeccCorridor.ObjectID))
oCorridor = TryCast(trans.GetObject(corridorId, _
OpenMode.ForRead), Corridor)
'cast succeeded?
If Not (oCorridor Is Nothing) Then
'yes! it is valid!
'do something here
End If
End Using 'this will Dispose the transaction object
This code was demonstrated with Corridor and AeccCorridor objects, but the same will work for any other object with AcadObject or ObjectId.