Edit: Inconsistent Naming, RhinoCommon, SubD Information From RhinoObject

When I see an object selected event, I check the types.

If it’s ObjectType.SubD, I try to get the SubD data via
SubDObject subd = (SubDObject) obj;
but I don’t see a property like subd.SubDGeometry or anything else to get a handle on the SubD instance itself.

Curves, Surfaces, and Breps have an intuitive structure (curve example shown):
CurveObject crv = (CurveObject) obj;
and then retrieve data or run methods on crv.CurveGeometry

EDIT: this seems to be stored on .Geometry, a naming difference from the other object types.

are your questions solved ?

Just to clarify - or for others that come along to this topic:

.Geometry
is calling a property of type “GeometryBase” of the base Class RhinoObject

Therefor all Rhino Objects have a GeometryBase:
https://developer.rhino3d.com/api/rhinocommon/rhino.docobjects.rhinoobject/geometry

The specialised properties like myCurveObject.CurveGeometry will allow code without casting.

workaround:
c# offers the nice “is” operator - that will allow a nice pattern

If (myGeometry is SubD mySubD)
{
    mySubD.DoSomethingWithit();
} else
{
    // myGeometry is not SubD 
   throw new NotImplementedException();
}

I think I may have what I needed particularly with your nudge to just try casting the .Geometry object to SubD, but I think this might still be an omission/bug.

I had thought that the API convention for RhinoObject types such as the curve I mentioned is:
Geometry for the base geometry
[specific]Geometry such as [Curve/Surface/Brep]Geometry for the details.

I can apparently cast RhinoObject.Geometry to SubD in the case where RhinoObject.ObjectType is SubD, but for API consistency it seems like the extra [specificclass]Geometry properties should be offered directly for all appropriate RhinoObject types.

If nothing else, doing that avoids requiring me to create a conditional with one branch the docs don’t tell me how to handle: if they don’t provide a dedicated property and I use something like ‘is’, what am I supposed to do if ObjectType == SubDObjectType but ‘is SubD’ doesn’t succeed and the cast throws an error? Undefined behavior it seems, which is bad.

throw new NotImplementedException();

(added above also)

make sure that the picking / object getting successfully returns a SubDObject.
then casting should always be successful.

But as you never now.
At least throwing an Exception is what I do in those cases.
Or if you don t like unhandled Exceptions:
…print an Error Message to the command line and return False / null / …

Functions like CurveGeometry are really just simple helper functions that perform the cast on Geometry for you.

@Tom_P Thanks, but that’s not the question I intended to ask. The question was why I should catch an exception and @stevebaer is captuting the reason why.

If I follow your (reasonable given the situation approach!), and working in C#, I have a big Switch statement which handles which object type I’m dealing with (ObjectType). I then peform a cast to get the details I want, and then I have a code branch to trap an error if the cast doesn’t actually work.

If that happens, where’s the error? Inside Rhino.

That’s why the API should provide such helper functions: an error on the cast, if it happens, is on Rhino’s side of the fence.

It also makes the on ramp for new developers, and unusual code paths for existing ones, much easier because the IDE tells you exactly what you can assign CurveGeometry to while just Geometry… you find out at runtime. You can also skip the cast entirely, in an error-safe way, if you only want to grab a property or two, or invoke a method or two:
int i = varname.CurveGeometry.[thingIwant]