Function Argument Validation: Comparing property size to a variable

4 次查看(过去 30 天)
I would like to ensure that a property of a class is of a certain size, defined by another property of the class which is set in the constructor. I can implement this by using a private property and set and get methods as shown in the code example below:
classdef TestClassI < handle
properties(SetAccess=immutable)
matrixSize single
end
properties(Dependent)
matrix single {mustBeNumeric}
end
properties(Access=private, Hidden=true)
matrix_
end
methods
function obj = TestClassI(matrixSize)
obj.matrixSize = matrixSize;
end
function matrix = get.matrix(obj)
matrix = obj.matrix_;
end
function set.matrix(obj, val)
validateattributes(val, {'numeric'}, {'size', obj.matrixSize});
obj.matrix_ = val;
end
end
end
However, this is pretty cumbersome. What I'd prefer to do is something like:
classdef TestClassII < handle
properties(SetAccess=immutable)
matrixSize single
end
properties
matrix(10,1) single {mustBeNumeric}
end
methods
function obj = TestClassII(matrixSize)
obj.matrixSize = matrixSize;
end
end
end
But, where (10,1) is not hard-coded but given by matrixSize. Is there a way to do this?

采纳的回答

Matt J
Matt J 2023-9-5
编辑:Matt J 2023-9-5
No, you can't do that, because the object has to be able to instantiate properties before the constructor is called.Therefore, property validation steps won't be able to use data that is only brought into existence later by the constructor.
My recommendation would be to overload subsasgn(). There, you can define any object-dependent validation steps that you want.
Or, if you really need the validation to be done even internally within the classdef, you could use matlab.mixin.indexing.RedefinesDot, though in my experience, that route can be more delicate.
  1 个评论
Bradley Treeby
Bradley Treeby 2023-9-5
编辑:Bradley Treeby 2023-9-5
> the object has to be able to instantiate properties before the constructor is called
Got it, that makes sense.
Note to my future self, it's also possible to do the same thing as I originally posted but without an internal variable. The MATLAB code analyzer warns against a set method accessing another property, but I think it's safe in this scenario, as matrixSize is declared as immutable.
classdef TestClassIII < handle
properties(SetAccess=immutable)
matrixSize single
end
properties
matrix single {mustBeNumeric}
end
methods
function obj = TestClassIII(matrixSize)
obj.matrixSize = matrixSize;
end
function set.matrix(obj, val)
validateattributes(val, {'numeric'}, {'size', obj.matrixSize});
obj.matrix = val;
end
end
end

请先登录,再进行评论。

更多回答(1 个)

Shubham
Shubham 2023-5-29
Hi Bradley,
Yes, there is a way to achieve this without the use of set and get methods. One possible solution is to use the validateattributes function in the constructor to check that the matrix property has the correct size. Here's an example implementation:
classdef TestClassII < handle
properties(SetAccess=immutable)
matrixSize single
end
properties
matrix single {mustBeNumeric}
end
methods
function obj = TestClassII(matrixSize)
obj.matrixSize = matrixSize;
defaultSize = [matrixSize, 1];
defaultMat = zeros(defaultSize, 'single');
validateattributes(defaultMat, {'numeric'}, {'size', defaultSize});
obj.matrix = defaultMat;
end
end
end
In this implementation, we initialize the matrix property using a default size of [matrixSize, 1] and fill it with zeros using the zeros function. Then we use validateattributes to check that the size of the default matrix is correct.
Note that validateattributes raises an error if the validation fails, so we only set obj.matrix if the validation succeeds.
  1 个评论
Bradley Treeby
Bradley Treeby 2023-9-5
编辑:Bradley Treeby 2023-9-5
Thanks! But this doesn't validate the size of obj.matrix if the values are changed outside the constructor right?

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Argument Definitions 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by