Create and lock a struct with fields in a class

조회 수: 26 (최근 30일)
henry won
henry won 2022년 5월 28일
편집: Matt J 2022년 5월 31일
I have a class and want to define a struct in that class with given fields (I do know how to do this), but then lock the fields of that structure. So, the user of that class can change values within that field, but not the structure itself. Similar to in C++ when you define a Struct; the access to it can be public, but the user can't change what the struct looks like. I've been playing around a lot with options, but it doesn't seem possible.
Example:
classdef myclass
%UNTITLED4 Summary of this class goes here
% Detailed explanation goes here
properties
x = struct('a',0,'b',1);
end
end
I can change x.a, etc which is good. But I can also say:
tmp = my_class;
tmp.x.c = 1;
And it creates the field c which I don't want to allow. I am trying to do this to only allow the user to change fields defined by the class itself. This will avoid someone thinking they set a variable but mispelled it, for example.
My workaround is to the property protected, then write some set function that first checks if it is already a field before setting it. Thanks for any advice!

답변 (2개)

Matt J
Matt J 2022년 5월 29일
편집: Matt J 2022년 5월 31일
One way:
classdef myclass
properties
x = struct('a',0,'b',1);
end
methods
function obj=set.x(obj,x)
try
obj.x=orderfields(x,obj.x);
catch
error 'Fields of obj.x are locked'
end
end
end
end
  댓글 수: 2
henry won
henry won 2022년 5월 31일
Not sure if this current answer does the right thing, but the example you had in here previously (I'm pasting it in here) does work, with the caveat that it only works when the property is a single layer struct, i.e. its fields are not structs themselves.
classdef myclass2
properties
x = struct('a',0,'b',struct('x',1));
end
methods
function obj = myclass2
%obj.x.c = 1;
end
function obj=set.x(obj,val)
% overrides obj.x = val;
% only checks first level of field compatibility
% all
if ~isempty(setxor(fieldnames(val), fieldnames(obj.x)))
error 'Fields are locked'
else
obj.x=val;
end
end
end
end
Matt J
Matt J 2022년 5월 31일
편집: Matt J 2022년 5월 31일
Not sure if this current answer does the right thing, but the example you had in here previously (I'm pasting it in here) does work
If it does work, and meets your needs, then I would be much obliged if you would Accept-click the answer.
with the caveat that it only works when the property is a single layer struct
If you mean that only the fields of obj.x are locked (not the fields of any structures x contains), then yes. However, it can only be called a caveat if your post had made any mention of such additional requirements.
What is the full extent of the locking that you imagined? Suppose I were to change obj.x.a=1 to a different data type like obj.x.a='fish'. Would you want to forbid things like that as well?

댓글을 달려면 로그인하십시오.


Ralf Ritter
Ralf Ritter 2022년 5월 31일
You could also define a class for property x.
This even allows you to specify the content/type of the fields a and b, if you use property validation:
classdef X
properties
a (1,1) double
b (1,1) double
end
methods
function obj = X(a,b)
obj.a = a;
obj.b = b;
end
end
end
And your myclass would be:
classdef myclass
properties
x = X(0,1);
end
end
If you then try to change a "field" (rather property) of x:
tmp = myclass;
tmp.x.c = 1;
This results in an error:
Unrecognized property 'c' for class 'X'.
And to demonstrate one of the benefits of property validation:
tmp.x.a = 'foo'
Error setting property 'a' of class 'X'. Value must be a scalar.
  댓글 수: 1
henry won
henry won 2022년 5월 31일
Thanks for the post. This is a good approach too. The downsides are that I'll end up with a lot of definition files, and like the previous post, it only works on a single layer. I mean that e.g. if x.b were a struct, a user could then add whatever fields to that struct they wanted (or by mistake). I realize I didn't specify that in my question, but I was actually looking for a more general struct declaration of sorts. These methods are all helpful though so thanks.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Construct and Work with Object Arrays에 대해 자세히 알아보기

제품


릴리스

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by