Different behavior casting in C# component and in Visual Studio!

Hi guys,

I am having a rather confusing moment here… which its kind of annoying because logically I don’t understand the reason of why its happening.

Here is what I am trying to do:

Loop through a List<object> check the type of each item, if the type of an item equals my specified type I will add it to a list. This works perfectly in a C# component but In Visual Studio it always evaluates to false. I am inputting that list under the pManager.AddGenericParameter() in VS.

Here is the code I used to test the same logic in a C# component:


    List<object> junk = new List<object>();

    junk.Add(1.0);
    junk.Add(SharpColor.Zero());
    junk.Add("hi");


    List<SharpColor> dataValues = new List<SharpColor>();

    for (int i = 0; i < junk.Count; i++)
    {

      if (junk[i].GetType() == typeof(SharpColor))
      {
        dataValues.Add((SharpColor) junk[i]);
      }
    }


    A = dataValues;

Here is the actual code in visual studio ( omitted some details for simplicity)

 protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
        {

            pManager.AddGenericParameter("Values", "V", "Values", GH_ParamAccess.list);
         
           
        }



        /// <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)
        {
            #region GATHER INPUT DATA

            List<object> _dataValuesTemp = new List<object>();
   

            DA.GetDataList(5, _dataValuesTemp);
  

            #endregion

            #region INITIALIZE DATA CLASS
            // Create Data object
    

                if (_dimension.EnvironmentDimension == EnvironmentDimension.Environment3D)
                {
                    switch (m_dataCategory)
                    {
                        case DataCategory.DifussionValues:
                            {
                                if (_reset)
                                {
                                    List<SharpColor> dataValues = new List<SharpColor>();

                                    for (int i = 0; i < _dataValuesTemp.Count; i++)
                                    {
                                       
                                        //**************************** Always evaluates to false!  
                                        if (_dataValuesTemp[i].GetType() == typeof(SharpColor))
                                        {
                                            dataValues.Add( (SharpColor)_dataValuesTemp[i] );
                                        }
                                       //**************************** Always evaluates to false!  
                                    }

                                    Data<SharpColor> m_Data = new GenerativeFloorPlans.Data.Data<SharpColor>(_xDim, _yDim, _zDim, m_dataCategory, dataValues);
                                    DA.SetData(0, new GH_ObjectWrapper(m_Data));
                                    

                                }


                               

                                break;
                            }

    


                    }



                   
                }

            #endregion

        }

Does anyone have any idea why this is happening? @DavidRutten do you have any insights? does it have to do with how the pManager.AddGenericParameter() is defined?

Thanks!

The instance of IGH_DataAccess provide you IGH_Goo wrappers, not the object you expect. Since they have automatic casting, it’s normal not to notice this. In GH1 each type must be wrapped with GH_Goo< T > where T is the your type, and parameters works with this IGH_Goo types, no directly with “T”.

So, what you should expect is a class that inherits GH_Goo< T >, and then call its Value property to get the object you expect. I’m not sure if GH_ObjectWrapper (which is a GH_Goo< object >) would work in your case, I think no but try it and if it works, is not the shortest way. We have the problem that the abstract class GH_Goo< T > is a generic class, so without knowing T we cannot use it (well, we can, using the System.Reflection namespace).

What scripting components do to cast automatically is call the ScriptVariable() method that belongs to IGH_Goo. I’m not sure it works, but you can try this:

  if (_dataValuesTemp[i] is IGH_Goo iGoo && iGoo.ScriptVariable() is SharpColor shCol)
  {
      dataValues.Add( shCol );
  }

If it doesn’t work, I’ll show you how to do it using Reflection.

2 Likes

Hey Dani,

yep, true thing, I tend to forget IGH_Goo is the base interface for all data related stuff in Grasshopper. I also didin’t know about the ScribtVariable() method thanks for bringing it up