How to CastTo a List<Q>?

i am doing a GH_Goo,and a Class with some mesh objest,i need to use GH_Goo to wrap this class. and the difficulty is :i know we can cast to a type,but how to cast to a List?
and this is code:

 public override bool CastTo<Q>(ref Q target)
    {
        if (typeof(Q).IsAssignableFrom(typeof(System.Object)))
        {
            object ptr = this.Value;
            target = (Q)ptr;
            return true;
        }
        else if (typeof(Q).IsAssignableFrom(typeof(List<GH_Mesh>)))
        {
            List<GH_Mesh> a = new List<GH_Mesh>();
            foreach (var rm in Value.Meshes)
            {
                GH_Mesh gms = new GH_Mesh(rm.GeoMesh);
                a.Add(gms);
            }
            object m = a;
            target = (Q)m;
            return true;
        }
        return false;
    }

The code above doesn’t work,because List<GH_Mesh>.
Thank you!

I don’t think you need to use System.Object or List<GH_Mesh>. In our code we use the following for a GH_Goo wrappers that need to implement CastTo<T>(ref T target)

public override bool CastTo<T>(ref T target)
{
  Type q = typeof(T);
  if (Value != null && Value.GetType().InheritsOrImplements(q))
  {
    target = (T)(object)Value;
    return true;
  }
  return base.CastTo(ref target);
}

Together with the InheritsOrImplements extension method:

/// <summary>
/// Extension methods for System.Type
/// </summary>
public static class TypeExtensionMethods
{
  /// <summary>
  /// Find out if a child type implements or inherits from the parent type.
  /// The parent type can be an interface or a concrete class, generic or non-generic.
  /// </summary>
  /// <param name="child"></param>
  /// <param name="parent"></param>
  /// <returns></returns>
  public static bool InheritsOrImplements([NotNull] this Type child, Type parent)
  {
    var currentChild = parent.IsGenericTypeDefinition && child.IsGenericType ? child.GetGenericTypeDefinition() : child;

    while (currentChild != typeof(object))
    {
      if (currentChild == null)
        return false;

      if (parent == currentChild || HasAnyInterfaces(parent, currentChild))
        return true;

      currentChild = currentChild.BaseType != null && parent.IsGenericTypeDefinition && currentChild.BaseType.IsGenericType
                          ? currentChild.BaseType.GetGenericTypeDefinition()
                          : currentChild.BaseType;
    }
    return parent == typeof(object);
  }

  private static bool HasAnyInterfaces([NotNull] Type parent, [NotNull] Type child)
  {
    return child.GetInterfaces().Any(childInterface =>
    {
      var currentInterface = parent.IsGenericTypeDefinition && childInterface.IsGenericType
                ? childInterface.GetGenericTypeDefinition()
                : childInterface;

      return currentInterface == parent;
    });

  }
}
public static bool IsList(Type type, Type argType)
{
  return type != null && type.IsGenericType &&
  type.GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>)) &&
  type.GetGenericArguments()[0] == argType;
}

I think the CastTo implementations assume a 1:1 relationship between the input and the result. Even if you could cast to a list, it wouldn’t behave like a list in grasshopper. If you explain a little more what the desired behavior of this type is from a user’s perspective, maybe we can provide better guidance.

2 Likes