Suggestions on how to get Nullable<T> type HasValue to be Set when using RTTIPROP.SetValue

Issue #86 closed
Todd Flora created an issue

Hi guys,

We have a serializer from NG that serializes to and from Objects using RTTI. When setting properties it uses the simple TRTTIProperty.SetValue method to set a value into a property.

Unfortunately when using the Spring Nullable<T> type the value is being set but none of the implicit operator overide methods seem to get called so the HasValue property is never set to @.

Therefore when Marshmallow tries to set the value for a Nullable based property into the Query Parameters it does not because HasValue is essentially false.

Is this a bug in the Nullable Record type or maybe we need to modify our Serializer code to do something to get the Implicit operators to work.

Any suggestions would be appreciated.

Comments (7)

  1. Stefan Glienke repo owner

    You must pass some TValue to SetValue. That TValue needs to contain a proper Nullable<T>. Implicit operator overloads are never called when using TValue. The TValueHelper from Spring.pas has methods to read and write the stored value of a Nullable<T>.

  2. Todd Flora reporter

    I am not seeing the TValueHelper running. I can't even set a break point as it looks like it is not linked into the source. Are there any tests that prove this code works?

    I have been struggling with this all day and would appreciate some confirmation that I am not running in circles.

    Thanks.

  3. Stefan Glienke repo owner

    The TValueHelper is not magically executing some code. ;) You have to call the methods it provides like SetNullableValue. And yes, many of the ORM tests are dealing with nullable values and the special TValueHelper methods for nullable handling

    "When setting properties it uses the simple TRTTIProperty.SetValue method to set a value into a property."

    I assume the serializer is taking lets say a string and assigning it by calling SetValue of a nullable<string> property? Well I wonder that it even assigns the value as it should raise an invalid cast. The serializer needs to handle Nullable explicitly. If you need help with that I suggest contacting LMD as I don't know their serializer.

  4. Todd Flora reporter

    It handles everything generically via RTTI. It passes things around using an untyped parameter. For instance when the data is retrieved from the Deserializer for a property say of type Nullable<T> the serializer calls the following method

    procedure Read(D : Deserializer; var V);
    

    The Read method returns a value of whatever type T is for the Nullable Record, then the following occurs with Prop being a TRttiProperty of type Nullable<SomeType>. At this point V is an untyped variable with the same type as SomeType

    Prop.SetValue(Instance, V);
    

    The Value.Cast does not fail and the value is set, but the HasValue is not being set because the implicit cast operators are not running.

    If I can create a test as an example I may send it to you. Thanks for your help.

  5. Todd Flora reporter

    You make me laugh. Do you actually think LMD is going to help me. :)

    Anyway. With your comments and a look at how you do it in the TValueHelper.SetNullableValue method I was able to figure it out.

    RTTI is awfulsome. Awful when trying to figure something out, but awesome once you get it.

    Thanks as always for your awesome help.

  6. Log in to comment