Setting a DataTree<GH_Curve> type as output

Hi, I (still) seem to have a problem with a custom component I made, that should output a datatree (storing block - parcel relationships). I get a Null Exception at
DA.SetData(0, dataTree);

What is going wrong here?

public class TestDataTree : GH_Component

    {

    
    public DataTree<GH_Curve> dataTree = new DataTree<GH_Curve>();
    public List<int> nrOfParcels { get; set; }

    /// <summary>
    /// Initializes a new instance of the C_TestDataTree class.
    /// </summary>
    public TestDataTree()
      : base("Test that Tree", "x",
          "x",
          "Tryout", "Optimisation")
    {
    }

    /// <summary>
    /// Registers all the input parameters for this component.
    /// </summary>
    protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
    { 
        pManager.AddCurveParameter("Blocks", "Blocks", " Add the blocks within which the parcels are located.", GH_ParamAccess.list);
        pManager.AddCurveParameter("Parcels", "Parcels", "Add the parcels as polyline curves.", GH_ParamAccess.list);
        pManager.AddCurveParameter("Buildable Parcels", "Buildable Parcels", "Add those parcels that are buildable (not predefined as green spaces or similar, optional).", GH_ParamAccess.list);
    

        pManager[2].Optional = true;
        
    }

    /// <summary>
    /// Registers all the output parameters for this component.
    /// </summary>
    protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
    {
        pManager.AddGenericParameter("data Tree", "data Tree", "data Tree", GH_ParamAccess.tree);
        
        
    }
    /// <summary>
    /// This is the method that actually does the work.
    /// </summary>
    /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
    protected override void SolveInstance(IGH_DataAccess DA)
    {
        InitializeDataTree(DA);
        DA.SetData(0, dataTree);
        
    }

    /// <summary>
    /// Provides an Icon for the component.
    /// </summary>
    protected override System.Drawing.Bitmap Icon
    {
        get
        {
            //You can add image files to your project resources and access them like this:
            //return Resources.IconForThisComponent;
            return null;
        }
    }

    /// <summary>
    /// Gets the unique ID for this component. Do not change this ID after release.
    /// </summary>
    public override Guid ComponentGuid
    {
        get { return new Guid("686e3dc4-9bc4-4e5f-ae1c-353d6f4fbfbe"); }
    }

    public void InitializeDataTree(IGH_DataAccess DA)
    {
        
        // read in blocks, conversion check
        List<Curve> _blocks = new List<Curve>();
        DA.GetDataList<Curve>(0, _blocks);

        List<GH_Curve> BlockCurves = new List<GH_Curve>();
        foreach (object item in _blocks)
        {
            if (item != null)
            {
                GH_Curve curveGoo = null;
                if (GH_Convert.ToGHCurve(item, GH_Conversion.Both, ref curveGoo))
                    BlockCurves.Add(curveGoo);
            } 
        }
        // read in parcels, conversion check 
        List<Curve> _parcels = new List<Curve>();
        DA.GetDataList<Curve>(1, _parcels);

        List<GH_Curve> ParcelCurves = new List<GH_Curve>();
        foreach (object item in _parcels)
        {
            if (item != null)
            {
                GH_Curve curveGoo = null;
                if (GH_Convert.ToGHCurve(item, GH_Conversion.Both, ref curveGoo))
                    ParcelCurves.Add(curveGoo);
            }
        }
        // read in buildable parcels, conversion check
        List<Curve> _buildParcelCurves = new List<Curve>();
        DA.GetDataList<Curve>(2, _buildParcelCurves);

        List<GH_Curve> BuildParcelCurves = new List<GH_Curve>();
        foreach (object item in _buildParcelCurves)
        {
            if (item != null)
            {
                GH_Curve curveGoo = null;
                if (GH_Convert.ToGHCurve(item, GH_Conversion.Both, ref curveGoo))
                    BuildParcelCurves.Add(curveGoo);
            }
        }

        List<GH_Curve> myParcelCurves = new List<GH_Curve>();
        
        // check if information on buildable areas has been passed by user, use respective curve collection
        if (BuildParcelCurves == null) myParcelCurves.AddRange(ParcelCurves);
        else myParcelCurves.AddRange(BuildParcelCurves);

        for (int i = 0; i < BlockCurves.Count; i++)   //for each block create path and fill in GH_Curve
        {
            Polyline block;
            bool cast = BlockCurves[i].Value.TryGetPolyline(out block);
            if (cast)
            {
                GH_Path pth = new GH_Path(i);
                dataTree.Add(BlockCurves[i], pth);
            }
            else { Exception e = new Exception("Block at index " + i + " is either invalid or not a polyline."); }

            int parcelPathIdx = 0;
            for (int j = 0; j < myParcelCurves.Count; j++)    //for each parcel check if in block, if yes, append to data tree 
            {
                Polyline parcel;
                bool cast2 = myParcelCurves[j].Value.TryGetPolyline(out parcel);
                if (cast2) 
                {
                    if (IsInside(parcel.CenterPoint(), block))
                    {
                        GH_Path pth2 = new GH_Path(i, parcelPathIdx);
                        dataTree.Add(myParcelCurves[j], pth2);
                        
                        /* child node of type List<GH_Number>, stores building parameters
                        List<GH_Number> buildingParams = new List<GH_Number>();
                        GH_Path pth3 = new GH_Path(i, parcelPathIdx, 0);
                        this.DataTree.AppendRange(buildingParams, pth3);*/

                        parcelPathIdx++;
                    }
                        
                }
                else { Exception e = new Exception("Parcel at index " + j + " is either invalid or not a polyline."); } 
            }
            int parcelNr = parcelPathIdx++;
            nrOfParcels.Add(parcelNr); 
            
        }         


    }

    //method that checks if point is inside curve
  public static bool IsInside(Point3d _pt, Polyline _crv) { //... }

}

You are calling nrOfParcels.Add() but never created a new List<>() instance. Somewhere you have to put this.nrOfParcels = new List();
Potentially in the constructor of the component, or in the SolveInstance() method.

On a side note, I think the general recommendation is to use GH_Structure<GH_Goo> in custom components and DataTree in script components. If you already have a tree with a type which implements <GH_Goo> that’s even easier to achieve…
Also conceptionally I don’t get the point in outsourcing everything of the RunScript method to another method.

thanks for your suggestions, problem solved!! i did not instantiate my tree in the right method, resulting in a null exception. And yes, I will ammend the type to GH_Struture as I want to use different data types in the tree. Thanks again, you have made my day!!