GH_GeometricGoo - Constructor Advice Needed

Hi C# guru’s,

I have created a GeometricGoo wrapper class based on examples found on this forum for a special beam class I have. All compiles well and the component works as intended.

I have the following question?

After running a Visual Studio Code Analysis on my Solution, it highlights the following warning.

It’s not breaking my application, but in my attempt to better my programming skill, I would like to know how to resolve it.

Part Code extract.

public class GH_Beam : GH_GeometricGoo<Beam>, IGH_PreviewData
    {
        #region constructors
        public GH_Beam()
        {
            this.Value = new Beam();
        }
        public GH_Beam(Beam beam)
        {
            if (beam == null)
                beam = new Beam();
            this.Value = beam;
        }
        .
        .
        .
        .
}

MicroSoft Docs Issue Link

Any advice or work around will be appreciated.

Hey @Big_G, try assigning directly to m_value

public class GH_Beam : GH_GeometricGoo<Beam>, IGH_PreviewData
{
    #region constructors
    public GH_Beam()
        : this(null)
    {
    }
    public GH_Beam(Beam beam)
    {
        if (beam == null)
            beam = new Beam();
        m_value = beam;
    }
    ...
}

This is the field that the GH_GeometricGoo<T>.Value property provides access to.

That’s weird though because Value is a property, not a method… What .NET Framework version are you using and what Visual Studio Version do you have? I tried to recreate the warning, but didn’t get CA2214 as you did. I have Visual Studio 2019 and .NET Framework 4.7.2.

 public abstract class GH_Goo<T>
    {
       protected T m_value;

        protected GH_Goo()
        {

        }

        public virtual T Value
        {
            get { return m_value; }
            set { m_value = value; }
        }
    }

public abstract class GH_GeometricGoo<T>: GH_Goo<T>
    {
        protected GH_GeometricGoo()
        { }
        public override T Value { get => base.Value; set => base.Value = value; }
    }

public class GH_Beam: GH_GeometricGoo<GH_Beam>
    {
        public GH_Beam()
        {
            this.Value = new GH_Beam();
        }
        public GH_Beam(GH_Beam beam)
        {
            if (beam == null)
                beam = new GH_Beam();
            this.Value = beam;
        }
    }

Hi @rawitscher-torres,

I am using 4.8

Hi @will,

I tried, but get this.

image

Is this a .net 4.8 issue. should I be using a earlier version with GH Component development.

EDIT: sorry @will, forgot to uncomment the second part.

I now get this error in stead

Replace this.Value with m_value in the second (uncommented) constructor.

Also, something to be aware of, Rhino itself targets .NET 4.5. Our installer ensures that this version of the framework is present on the user’s computer. If you target a newer version then you’ll need to make sure that your users have it installed. Since the May 2019 update, Windows 10 now includes .NET 4.8 by default, but not everyone will be up to date.

@will,

Thanks for your advice. This solved the issue.

Also thanks for the advice on .NET 4.8. I am reverting back to 4.5 as our company does not update often.

1 Like

If you want to keep your code more reduced, you can also just call the base constructor:

    public BeamGoo(Beam beam) : base (beam)
    {
    }

That will automatically assign the object passed to m_value

Or if you really want to create an empty beam object in the case that it was null before:

    public BeamGoo(Beam beam) : base (beam ?? new Beam())
    {
    }

I don’t really understand in which scenario this makes sense though, if for some reason the value is null, I’d rather check for nullity instead of checking for validity of fields of the (empty) beam object… To give an example, using some fields/methods of Value inside your BeamGoo (for example for serialization, casting, drawing, etc.) it will still fail, because your object is empty or only contains default values.

1 Like

@dsonntag,

Thanks for your comments and they are certainly valid.
I have a Beam Class that typically creates a Brep, has a axis of type Line() and a few properties like Id, name etc.

I do come across very rare cases where the Brep fails and therefore I have a null value.

I pretty much worked without a Goo wrapper, but found to pass all this info around all the time, required too many input and output ports on the components.

I entered into the GH_GeometricGoo<T> challenge.

I have had some very good help from David Rutten in getting it all to work, but to be honest, the constructor thingy is still not very clear to me.

If you inherit from GH_GeometricGoo<T>, IGH_PreviewData, you are not required to create a constructor in the wrapper class, but need to one to deal with DuplicateGeometry()

This is where the wheels come off.

I basically used this example by David to follow.
Boat.cs (16.4 KB)

I understand that your Brep can fail, but that would be on the level of the design of the beam object. Is it usefull, when the brep fails? Does it allow the brep to be null or will it throw an exception?

On the level of the GeometricGoo and its constructors, I am not sure why you would have to handle the case of the null beam object differently. I don’t even know exactly, where they can occur in the first place. But if the constructor of your BeamGoo is called with a null object, then the fields m_value gets assigned null. You just need to make sure, that e,g, when the preview method is called you check that Value is not null before accessing its fields, else an NullReferenceException will be thrown. But if you allow null objects inside the constructor of the beam object, you need to do those checks for the individual fields anyways.

In my opinion, if the object the goo wrapper holds, is null, duplication should not create an empty or default object, but it should also return null. You can deal with that inside the DuplicateGeometry() method and return null if value is null and else call its duplication method.