DataTree<T> or GH_Structure<T> in Visual Studio

Hello,
Im working on simple grasshopper components in Visual Studio written in C#.
I can remember to have heard somewhere I should not use the DataTree Class in Visual Studio.
After I did some research in the RhinoCommon library, I found a note for the DataTree Class saying:
Implements basic Grasshopper Data Tree functionality in an easy-to-use class. This class is used primarily in Scripting components. If you’re using the Grasshopper SDK you should consider using the GH_Structure class instead.

What does this note mean? Does somebody know if I can use the DataTree Class without problems?
And does anybody know or has resources with wich I could learn the GrasshopperSDK?
Thanks for reading my message!
Best wishes,
Oliver

The DataTree class was added later to simplify working with trees in scripting components. I believe for full functionality you should use GH_Structure. The primary difference is that you can have a DataTree of any type, like DataTree<double>, whereas a GH_Structure must wrap a type that implements the IGH_Goo Interface (e.g. GH_Structure<GH_Boolean>). When you create an input or output parameter with GH_ParamAccess.Tree as its param access, I believe it is designed to produce / accept GH_Structures. There’s a chance it’s been expanded to accept DataTree types as well, but for maximum control and consistency I’d recommend working with GH_Structure.

Thank you Andrew! Then I will use the GH_Structure in the future!
I think I ran into trouble using DataTree once. Now I know the reason why.
Best wishes, Oliver

GH_Structure also guarantees better performance since it forces you to use native grasshopper types that implement the IGH_Goo interface. Bypassing the heavy conversion that goes on under the hood to convert RhinoCommon types to GH types. This is the main reason why outputing a GH_Point is much faster than outputing Point3d.

Thank you Nicholas for your point.
That brings me to another question.
What do you guys think is the best practice, when dealing with lists in a list inside a component?
I do not know if my question is correct, but what I meant is should I use GH_Structures inside a component or should I prefer C# Arrays and only output my Array as a GH_Structure.
What I have recognized is that GH_Structures only accept Grasshopper.Kernel.Types, but with these I can’t use the rhinocommon library.
So I think I should use GH_Structure only when outputting an Array.
Thanks for reading.

Best wishes, Oliver

Well it really depends what is your overall goal. If you would like to have your library Grasshopper independent, meaning you could re-use your code in other .NET friendly applications like Revit, Dynamo, Unity, etc. In my opinion is best to use the native C# data structures. Just wrap up your code in the VS template to develop GH plugins, the one that inherits form GH_Component. So basically the Grasshopper component in the end will be sort of like your frontend part of the code, here you can output your data using the GH_Structure<T> while keeping the native C# data structures at the core of your library. If you have your own types you can just create your own compatible types by inheriting from IGH_Goo

For example this class inherits from GH_GeometricGoo<T> where T is your own .NET object
It will then need to implement all the necessary inherited members marked by the override keyword.

After you successfully implemented the class, then GH_Structure<T> will accept SharpColor_GH


 public class SharpColor_GH : GH_GeometricGoo<SharpColor.SharpColor>
    {

        public override SharpColor.SharpColor Value

        {
            get { return base.Value; }
            set { base.Value = value; }
        }

  


        private BoundingBox _bbox = BoundingBox.Unset;


        /// <summary>
        /// 
        /// </summary>
        public SharpColor_GH()
        {
        }




        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public SharpColor_GH(SharpColor.SharpColor value)
        {
            Value = value;

        }


     


        // <inheritdoc />
        public override bool IsValid
        {
            
        }


        /// <inheritdoc />
        public override string TypeName
        {
           
        }


        /// <inheritdoc />
        public override string TypeDescription
        {
           
        }


        /// <inheritdoc />
        public override BoundingBox Boundingbox
        {
           
        }



        // <inheritdoc />
        public override IGH_Goo Duplicate()
        {
          
        }


        // <inheritdoc />
        public override IGH_GeometricGoo DuplicateGeometry()
        {
            
        }


        // / <inheritdoc />
        public override string ToString()
        {
            return Value.ToString();
        }


        /// <inheritdoc />
        public override object ScriptVariable()
        {
            return Value;
        }


        // / <inheritdoc />
        public override bool CastTo<T>(ref T target)
        {
            
        }


        /// <inheritdoc />
        public override bool CastFrom(object source)
        {
            
        }


        /// <inheritdoc />
        public override BoundingBox GetBoundingBox(Transform xform)
        {
            var b = Boundingbox;
            b.Transform(xform);
            return b;
        }


        /// / <inheritdoc />
        public override IGH_GeometricGoo Transform(Transform xform)
        {
           
        }


        /// <inheritdoc />
        public override IGH_GeometricGoo Morph(SpaceMorph xmorph)
        {
           
        }


    }// END CLASS

https://developer.rhino3d.com/api/grasshopper/html/N_Grasshopper_Kernel_Types.htm

Hello Nicholas. Sorry for the late answer. I did go with your suggestion.
Thank you very much!
Best wishes ,
Oliver