ReSharper является инструментом Visual Studio, не инструментом языка. Самый близкий эквивалент был бы ИДЕЯ IntelliJ от людей, которые создали ReSharper.
К сожалению, все элементы массива в MATLAB должны быть одного типа. Когда вы объединяете разные классы, MATLAB попытается преобразовать их все в один и тот же класс.
Если вы определили один из ваших классов как подчиненный или превосходящий другой (с помощью атрибута InferiorClasses или функции INFERIORTO / SUPERIORTO ), затем вызываются методы более высокого класса. Если вы не указали отношения между классами, тогда два объекта имеют равный приоритет, и MATLAB вызывает метод самого левого объекта. Вероятно, поэтому arr = [bc];
создает массив класса B, а arr = [cb];
создает массив класса C.
Если вы хотите выполнить метод foo
, определенный для класса B на объекте b
, а также выполнить метод foo
, определенный для класса C на объект c
, то вам, вероятно, придется использовать массивы ячеек и функцию CELLFUN . Если foo
не возвращает значение, вы можете сделать что-то вроде этого:
arr = {b,c};
cellfun(@foo,arr); % Invoke foo on each element of the cell array
Ради интереса я придумал возможное решение, которое технически работает, но имеет некоторые ограничения. Чтобы проиллюстрировать идею, я собрал несколько примеров классов, подобных тем, которые вы указали в вопросе. Вот абстрактный суперкласс classA
:
classdef classA < hgsetget
properties
stuff
end
properties (Access = protected)
originalClass
end
methods
function foo(this)
disp('I am type A!');
if ~strcmp(class(this),this.originalClass)
this = feval(this.originalClass,this);
end
this.fooWorker;
end
end
methods (Abstract, Access = protected)
fooWorker(this);
end
end
И вот ' s пример подкласса classB
( classC
точно такой же, где везде B
заменено на C
и наоборот):
classdef classB < classA
methods
function this = classB(obj)
switch class(obj)
case 'classB' % An object of classB was passed in
this = obj;
case 'classC' % Convert input from classC to classB
this.stuff = obj.stuff;
this.originalClass = obj.originalClass;
otherwise % Create a new object
this.stuff = obj;
this.originalClass = 'classB';
end
end
end
methods (Access = protected)
function fooWorker(this)
disp('...and type B!');
end
end
end
Конструкторы для classB
и classC
разработаны таким образом, что два класса могут быть преобразованы друг в друга. Свойство originalClass
инициализируется при создании и указывает, каким был исходный класс объекта. Это свойство останется неизменным, если объект преобразован из одного класса в другой.
В методе foo
текущий класс переданного объекта проверяется на соответствие его исходному классу. Если они отличаются, объект сначала преобразуется обратно в исходный класс перед вызовом метода fooWorker
. Вот тест:
>> b = classB('hello'); % Create an instance of classB
>> c = classC([1 2 3]); % Create an instance of classC
>> b.foo % Invoke foo on b
I am type A!
...and type B!
>> c.foo % Invoke foo on c
I am type A!
...and type C!
>> arr = [b c] % Concatenate b and c, converting both to classB
arr =
1x2 classB handle
Properties:
stuff
Methods, Events, Superclasses
>> arr(1).foo % Invoke foo on element 1 (formerly b)
I am type A!
...and type B!
>> arr(2).foo % Invoke foo on element 2 (formerly c)
I am type A!
...and type C!
Одно из ключевых ограничений (помимо того, что оно немного некрасиво) - это случай, когда classB
и classC
каждый имеет свойства, которых нет у другого. В таком случае преобразование в другой класс и последующее преобразование обратно, скорее всего, приведет к потере этих свойств (т.е. сбросу до значений по умолчанию). Однако, если бы один класс был подклассом другого, так что у него были бы все те же свойства и они, есть решение. Вы можете установить подкласс выше суперкласса (см. Обсуждение выше), чтобы конкатенация объектов двух классов всегда приводила к преобразованию объектов суперкласса в подкласс. При обратном преобразовании в "полиморфные" методы (например, foo
выше) данные объекта не будут потеряны.
Я не делаю этого. Я не знаю, насколько это работоспособное решение, но, возможно, оно даст вам хотя бы несколько интересных идей. ;)