Main Content

matlab.mixin.CustomElementSerialization Class

Namespace: matlab.mixin

Customize how objects are serialized and deserialized

Since R2024b

Description

Inherit from this class to customize how objects are serialized (saved) and deserialized (loaded). For example, the methods of this mixin enable you to change the content of objects when they are serialized or deserialized to maintain compatibility between old and new definitions of the class of those objects.

Class Attributes

Abstract
true
HandleCompatible
true
Hidden
true

For information on class attributes, see Class Attributes.

Methods

expand all

Examples

collapse all

Define a class TestResults that represents experimental results for a test performed on some material. The Data property contains the results of two tests, one in each row of the 2-by-n matrix.

classdef TestResults < handle
    properties
        Material {mustBeText} = ""
        Data (2,:) {mustBeNumeric}
    end

    methods
        function obj = TestResults(m,d)
            obj.Material = m;
            obj.Data = d;
        end
    end
end

Create an instance of TestResults and save it. Replace yourfilepath with your local path.

a35 = TestResults("Sample A35",[1 0 1; 1 2 1]);
save("yourfilepath/Test.mat","a");

Revise the class definition so that the results of the two tests are also stored in separate properties, TrialData1 and TrialData2. To maintain full compatibility between objects serialized under both definitions, make these changes to the class:

  • Inherit from matlab.mixin.CustomElementSerialization.

  • Add the TrialData1 and TrialData2 properties as transient. Transient properties are not serialized by default.

  • Add the attributes Dependent and GetObservable to the Data property. Define its value in its get method as the concatenation of TrialData1 and TrialData2. Define the set method of Data to update TrialData1 and TrialData2.

  • Implement the static method modifyOutoingSerializationContent. This method is called whenever you attempt to save a TestResults object. The Material property is saved automatically, but the other properties are transient and dependent, which means they are not serialized by default. This method uses the addNameValue method of matlab.serialization.ElementSerializationContent to serialize the dependent Data property and its current value. The first version of the class defines the Data property but not TrialData1 and TrialData2. Serializing only Data enables users working with the first version of the class to deserialize objects saved with the revised class definition.

  • Implement the static method modifyIncomingSerializationContent. This method is called whenever you attempt to load a TestResults object. This method loads the Data property and copies the appropriate data into the TrialData1 and TrialData2 properties. This strategy enables users working with the revised version of the class to load objects saved with the old class.

  • Implement the static method finalizeIncomingSerialization. This method is called after the object has been deserialized. Use this method to add an event listener for the Data property. Add the callback method handlePropertyEvents to the main body of the class.

classdef TestResults < handle & matlab.mixin.CustomElementSerialization
    properties
        Material {mustBeText} = ""
    end

    properties (Transient)
        TrialData1 (1,:) {mustBeNumeric}
        TrialData2 (1,:) {mustBeNumeric}
    end

    properties (GetObservable,Dependent)
        Data
    end

    methods
        function obj = TestResults(m,d)
            obj.Material = m;
            obj.TrialData1 = d(1,:);
            obj.TrialData2 = d(2,:);
        end

        function val = get.Data(obj)
            val = [obj.TrialData1; obj.TrialData2];
        end

        function set.Data(obj,val)
            arguments
                obj
                val (2,:)
            end
            obj.TrialData1 = val(1,:);
            obj.TrialData2 = val(2,:);
        end
    
        function handlePropertyEvents(~,~,~)
            disp("Data updated.")
        end
    end

    methods (Static)
        function modifyIncomingSerializationContent(sObj)
            if sObj.hasNameValue("Data")
                allData = sObj.Data;
                sObj.addNameValue("TrialData1",allData(1,:));
                sObj.addNameValue("TrialData2",allData(2,:));
            end
        end
        function modifyOutgoingSerializationContent(sObj,obj)
            sObj.addNameValue("Data",obj.Data);
        end
        function obj = finalizeIncomingObject(obj)
           addlistener(obj,"Data","PostGet",@obj.handlePropertyEvents);
        end
    end
end

Clear a35 from memory.

clear("a35")

Remove the old definition of TestResults from your path. Add the revised definition of TestResults to the path, and load the a35 object. Display the object to confirm that the variable has been deserialized as an object of the revised definition of TestResults

load("yourfilepath/Test.mat","a35");
a35
a35 = 

  TestResults with properties:

      Material: "Sample A35"
    TrialData1: [1 0 1]
    TrialData2: [1 2 1]
          Data: [2×3 double]

Change the value of TrialData1 to test the property event listener. The event is triggered when MATLAB calls the get method for Data when it displays the class details.

a35.TrialData1 = [1 -1 1]
a35 = 

Data updated.
  TestResults with properties:

      Material: "Sample A35"
    TrialData1: [1 -1 1]
    TrialData2: [1 2 1]
          Data: [2×3 double]

Reverse this procedure and save an object under the new definition of TestResults.

b47 = TestResults("Sample B47",[0 1 1; 3 2 1])
b47 = 

  TestResults with properties:

      Material: "Sample B47"
    TrialData1: [0 1 1]
    TrialData2: [3 2 1]
          Data: [2×3 double])
save("yourfilepath/NewTest.mat","b47");

Clear b47 from memory.

clear("b47")

Remove the new definition of TestResults from your path. Add the old definition of TestResults to the path, and load the b47 object. Display the object to confirm that the variable has been deserialized as an object of TestResults and the data has been preserved.

load("yourfilepath/NewTest.mat","b47");
b47.Data
ans =

     0     1     1
     3     2     1

Version History

Introduced in R2024b