Hello,
I have this function (below) that that deletes a layer.
I am looping thru an array of names that I want deleted.
Two Things:
Visual Studio is warning:
Function 'LayerDelete' doesn't return a value on all code paths. A null reference exception could occur at run time when the result is used.
And this Error:
Unhandled Exception.... Operation is not valid sue to the current state of the object.
FATAL ERROR
The code was an answer to another question (which worked), but now that I tweaked it Im having issues...
How can I fix the code so It doesnt crash and that "it returns a value on all code paths"?
Function LayerDelete(ByVal db As Database, ByVal layerName As String) As String If (layerName = "0") Then Return "Layer '0' cannot be deleted." End If Dim tr As Transaction = db.TransactionManager.StartTransaction Dim layerTable As LayerTable = CType(tr.GetObject(db.LayerTableId, OpenMode.ForRead), LayerTable) If Not layerTable.Has(layerName) Then Return ("Layer '" + (layerName + "' not found.")) End If Try 'Dim layerId As Object = layerTable(layerName) Dim layerId As ObjectId = layerTable(layerName) If Application.GetSystemVariable("Clayer") = layerName Then Return "Current layer cannot be deleted." End If Dim layer As LayerTableRecord = CType(tr.GetObject(layerId, OpenMode.ForWrite), LayerTableRecord) layer.IsLocked = False Dim blockTable As BlockTable = CType(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable) 'For Each btrId As Object In blockTable For Each btrId As ObjectId In blockTable Dim block As BlockTableRecord = CType(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord) 'For Each entId As Object In block For Each entId As ObjectId In block Dim ent As Entity = CType(tr.GetObject(entId, OpenMode.ForRead), Entity) If (ent.Layer = layerName) Then ent.UpgradeOpen() ent.Erase() End If Next Next layer.Erase() tr.Commit() 'MsgBox("Layer '" + (layerName + "' have been deleted.")) Catch e As System.Exception MsgBox("Error: " + e.Message) End Try End Function
Solved! Go to Solution.
Solved by Keith.Brown. Go to Solution.
I am not a VB.Net guy but it looks like you are not returning a value inside of your catch statement. This is a valid code path so your function needs to return a value from it. You should set a default value for your string and either return it or just return null. You could also throw the error up to the calling function.
Also you have created a transaction but you are not disposing of it anywhere. Transactions impliment IDisposable so they must be disposed. You can make this easy by always declaring your Transactions inside a using statement. This will insure that Dispose is called automatically when leaving the Using block of code.
You can read about the using statement here. http://msdn.microsoft.com/en-us/library/htd05whh.aspx and here. http://adndevblog.typepad.com/autocad/2012/05/two-common-mistakes-with-transactions.html
This might not completely fix your errors but they are two that I see from glancing at it quickly.
Thanks,
I modified the IF with an else that does tx.dispose() before the end of the function and that took care of it.
As far as returning the right code path I'm not quite too sure at the moment, but its not causing major errors at the moment so i'll place it on the back burner for now.
Tony