Avoid warning “a set method for non-dependent prop

2019-02-26 21:16发布

问题:

I have a class which has some properties and 2 are related, in the example called param1, param2. They are independent, just constrained. param2 must be as large or larger than param1 and must always exist if param1 does. Code in question is something like:

    function set.param1(obj, input)
        disp('setting param1')
        obj.param1 = input;
        if (isempty(obj.param2) || obj.param2 < obj.param1) % Warning on param2
           obj.param2 = obj.param1; % Warning on param2
        end
    end

Similar code for the set.param2. Code works fine and I cannot see any better way to do it. The problem - it produces warning "a set method..." like mentioned in title. I suppressed them for the lack of better solution. Is there a better way to achieve this functionality and without warnings? Obviously not a hacky "solution" like a hidden function SetParam2:

function SetParam2(obj, input)
   obj.param2 = input;
end

which confuses editor just enough it doesn't complain.

回答1:

You could use two layers of properties

  • one layer which is exposed and Dependent
  • one layer which is private and actually stores the values

The similar technique is used here in the documentation: Avoid Property Initialization Order Dependency.

classdef TestClass < handle  
    properties (Access = private)
        privateParam1;
        privateParam2;
    end

    properties (Dependent)
         param1;
         param2;
    end

    methods
        function p1 = get.param1(obj)
            p1 = obj.privateParam1;
        end

        function p2 = get.param2(obj)
            p2 = obj.privateParam2;
        end

        function set.param1(obj, input)
            obj.privateParam1 = input;
            if (isempty(obj.privateParam2) || obj.privateParam2 < obj.privateParam1)
                obj.privateParam2 = obj.param1; 
            end
        end

         function set.param2(obj, input)
            if (~isempty(obj.privateParam1) && obj.privateParam1 > input)
                obj.privateParam2 = obj.privateParam1;
            else
                obj.privateParam2 = input;
            end
         end
    end
end

The trick here: privateParam1 and privateParam2 stores the two values. The get and set only implemented for the exposed properties param1 and param2: the get returns simply the inner property and in the set both of them can be used without the analyzer warning as they are marked as Dependent.