Accessing object properties through reflection in C#

Hey HB team.

I am trying to use a custom C# component to interrogate a HB object. I want to use C# reflection to access the values but am not able to get through all the layers of nested properties.

For example, if I write the code in python like so I can access the u_value parameter:
x.properties.energy.construction.u_value

But I am unable/unsure how to do this in a C# node.
Is anyone able to help me with this?

Cheers

1 Like

I tested using the HoneybeeSchema.
I created a JSON file using a python component and serialized a face from the dictionary.

dic = face.to_dict()
a = json.dumps(dic)

but once a use Face.FromJson into a C# component in GH I have this error, even if the DLL is referenced.
1. Error (CS0012): The type 'System.ComponentModel.DataAnnotations.IValidatableObject' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. (line 58)

If I use Face.FromJson into a custom component, I am dealing with this kind of error.

@chris and @MingboPeng any suggestions?
I can’t upload the file because I am a new user.

This is the Json

{"display_name": "Walls_Rv", "identifier": "Walls_Rv_6bd0662f_0", "geometry": {"type": "Face3D", "plane": {"o": [-2.0, -0.5, 0.0], "n": [0.0, -1.0, 0.0], "type": "Plane", "x": [1.0, 0.0, 0.0]}, "boundary": [[-2.0, -0.5, 0.25], [-2.0, -0.5, 0.0], [2.0, -0.5, 0.0], [2.0, -0.5, 0.25]]}, "face_type": "Wall", "boundary_condition": {"view_factor": {"type": "Autocalculate"}, "sun_exposure": true, "wind_exposure": true, "type": "Outdoors"}, "type": "Face", "properties": {"radiance": {"type": "FaceRadianceProperties"}, "energy": {"construction": {"display_name": "Walls_Rv", "type": "OpaqueConstruction", "identifier": "Walls_Rv", "materials": [{"conductivity": 0.2142857142857143, "specific_heat": 920.0, "density": 2000.0, "thermal_absorptance": 0.90000000000000002, "thickness": 0.29999999999999999, "solar_absorptance": 0.59999999999999998, "visible_absorptance": 0.59999999999999998, "display_name": "Walls_Rv", "roughness": "MediumRough", "type": "EnergyMaterial", "identifier": "Walls_Rv"}]}, "type": "FaceEnergyProperties"}, "type": "FaceProperties"}}

Blockquote

@chris any suggestions?

Hi @sonomirco

Try to set “abridged” to True when you convert HB objects to a dictionary. On the C# side, it mostly only works with “abridged” objects.

Python:

dic = face.to_dict(abridged=True)
a = json.dumps(dic)

CSharp:

var Face = HoneybeeSchema.Face.FromJson(a);
1 Like

You can also use dynamic.

So declare your variable as a dynamic type, then you can access all the properties. Although you won’t get any autosuggest/intellisense and also will throw exception at runtime if that property doesn’t exist.

dynamic myDynamicInstance = myInstance;
dynamic shades = myDynamicInstance.Shades;

Etc.

1 Like

Take a look here for more dynamic explanation

2 Likes

Or see a hb legacy implementation of dynamic here

1 Like

Thanks @Mathiassn
this is an even simpler solution!