Creating a hard link among properties of an object?

3 次查看(过去 30 天)
Hello,
I have a class called Module that has 3 properties: InternalVariables, ExternalVariables, and AllVariables. InternalVariables and ExternalVariables both contain symbolic column vectors. I want to define AllVariables as the superposition of InternalVariables and ExternalVariables, and if I change either InternalVariables or ExternalVariables, AllVariables gets updated automatically. Is there a way to do this by using a hard link?
Thank you,
Kevin

采纳的回答

Sean de Wolski
Sean de Wolski 2014-5-13
A couple of thoughts
Why not just make AllVariables a dependent property. Then every time it's queried it's calculated on the fly. MATLAB passes by reference so unless you have thousands of variables this should not be a performance penalty.
Another approach would be with listeners. The basic plan would be to have the constructor set listeners for changes to internal and external properties. This avoids having to have an explicit setter for each property. Of course, having an explicit setter for each property isn't necessarily a bad thing, especially if you need to validate the new property values anyway. In fact, I would probably just take this approach and use a setter every time.
  4 个评论
Cedric
Cedric 2014-5-13
编辑:Cedric 2014-5-13
I built really fast a dummy example to illustrate
classdef TestClass < handle
properties
intVars
extVars
allVars
end
methods
function obj = TestClass()
obj.intVars = struct( 'a', 8:15, 'b', -3 ) ;
obj.extVars = struct( 'c', 7, 'd', 8 ) ;
end
function value = get.intVars( obj ), value = obj.intVars ; end
function set.intVars( obj, value ), obj.intVars = value ; end
function value = get.extVars( obj ), value = obj.extVars ; end
function set.extVars( obj, value ), obj.extVars = value ; end
function value = get.allVars( obj )
% If accessing e.g. TestClass.allVars.c, how do I know here
% that field 'c' was addressed => how can I pick extVars?
end
function set.allVars( obj, value )
% If accessing e.g. TestClass.allVars.c, how do I know here
% that field 'c' was addressed => how can I pick extVars?
end
end
end
On that note, have a good night! I'll be back tomorrow to go on the discussion.
Sean de Wolski
Sean de Wolski 2014-5-13
I don't have much time right now (so will probably have to continue this tonight) but here the better of the two approaches I had in mind:
In the getter (recommended!)
classdef TestClass < handle
properties
intVars
extVars
end
properties (SetAccess = protected, Transient = true, Dependent = true)
allVars
end
methods
function obj = TestClass()
obj.intVars = struct( 'a', 8:15, 'b', -3 ) ;
obj.extVars = struct( 'c', 7, 'd', 8 ) ;
end
function val = get.allVars(obj)
val = obj.intVars;
fns = fieldnames(obj.extVars);
for ii = 1:numel(fns)
val.(fns{ii}) = obj.extVars.(fns{ii});
end
end
end
end
To use it:
T = TestClass
T.allVars
T.intVars.Hwllo = pi
T.allVars
T.extVars.World = exp(1)
T.allVars

请先登录,再进行评论。

更多回答(1 个)

Cedric
Cedric 2014-5-12
编辑:Cedric 2014-5-13
NOTE: well, I spent an hour stuck in a mall with a tornado warning, so I had a little time to extend my first example. See EDIT below.
Did you try using setters and getters for these properties (in conjunction with dependent properties)? If they are stored in structs (and not as public/private/etc groups of properties), you may have to use subsasgn / subsref / substruct, etc.
EDIT : here is a new version of my previous example, which delegates indexing appropriately (I suppose, but I didn't have time to test) when fields of allVars contain arrays or structs.
classdef TestClass < handle
properties
intVars
extVars
allVars
end
methods
function obj = TestClass()
obj.intVars = struct( 'aInt', 3, 'bInt', 20:30, 'c', 7 ) ;
obj.extVars.dExt = struct( 'x', -2, 'y', 48 ) ;
obj.extVars.eExt = {'Hello', 'World'} ;
obj.extVars.c = 8 ;
end
function value = subsref( obj, S )
if length(S) > 1 && all( [S(1:2).type] == '.' ) && ...
strcmp( S(1).subs, 'allVars' )
is_int = isfield( obj.intVars, S(2).subs ) ;
is_ext = isfield( obj.extVars, S(2).subs ) ;
if is_int && is_ext
valueInt = obj.subsref_delegate( obj.intVars.(S(2).subs), S ) ;
valueExt = obj.subsref_delegate( obj.extVars.(S(2).subs), S ) ;
value = struct( 'int', valueInt, 'ext', valueExt ) ;
elseif is_int
value = obj.subsref_delegate( obj.intVars.(S(2).subs), S ) ;
else
value = obj.subsref_delegate( obj.extVars.(S(2).subs), S ) ;
end
else
value = builtin( 'subsref', obj, S ) ;
end
end
function obj = subsasgn_TODO( obj, S, value )
% .. your move.
end
end
methods (Static)
function value = subsref_delegate( x, S )
if length( S ) > 2
value = builtin( 'subsref', x, S(3:end) ) ;
else
value = x ;
end
end
end
end
With that..
>> tc = TestClass() ;
>> tc.intVars
ans =
aInt: 3
bInt: [20 21 22 23 24 25 26 27 28 29 30]
c: 7
>> tc.extVars
ans =
dExt: [1x1 struct]
eExt: {'Hello' 'World'}
c: 8
>> tc.extVars.dExt.x
ans =
-2
>> tc.allVars.aInt
ans =
3
>> tc.allVars.bInt
ans =
20 21 22 23 24 25 26 27 28 29 30
>> tc.allVars.bInt(7)
ans =
26
>> tc.allVars.c % c is a common property => output struct with int/ext values.
ans =
int: 7
ext: 8
>> tc.allVars.eExt{2}
ans =
World
>> tc.allVars.dExt.y
ans =
48
  4 个评论
Sean de Wolski
Sean de Wolski 2014-5-14
Interesting comment on the tornado warning - I wonder if it was the same one that kept me at the hotel yesterday outside of Detroit.

请先登录,再进行评论。

类别

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

Community Treasure Hunt

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

Start Hunting!

Translated by