Я использую оценщик выражений JCL TEvaluator (чудесное творение, подаренное Барри Келли). (Спасибо, Барри!)
фон
я использовал метод AddFunc.
function MyFunc:double;
begin
// calculations here
Result:=1;
end;
вы можете использовать метод AddFunc, чтобы сделать функцию доступной:
AddFunc('MyFunc', MyFunc);
вот в чем проблема...
мне нужно вызвать метод объекта вместо отдельной процедуры.
причина в том, что у меня есть список объектов, которые предоставляют значения.
скажем, у нас есть список транспортных средств. каждый объект имеет функцию веса. я хочу иметь возможность сделать доступным вес каждого объекта для использования в формуле.
глупый пример, но его легко объяснить:
type
TVehicle=class
private
public
function Weight:double;
end;
function StrangeCalculation:double;
var
vehicle:TVehicle;
begin
for iVehicle = 0 to Count - 1 do
begin
vehicle:=GetVehicle(iVehicle);
// E2250 There is no overloaded version of 'AddFunc' that can be called with these arguments
eval.AddFunc(vehicle.Name, vehicle.Weight);
end;
Result:=eval.Evaluate('JeepTJWeight + FordF150Weight * 2');
end;
мои варианты:
AddVar() или AddConst() -- но это не так уж хорошо, потому что мне нужно иметь возможность вызвать исключение, если значение недоступно.
AddFunc() с автономными функциями. не может этого сделать, потому что имена (и количество) переменных неизвестны до времени выполнения.
измените объект, чтобы добавить обратный вызов, если переменная не найдена. Я действительно сделал это, но мне нужно было отредактировать копию источника, чтобы перезвонить, чтобы он сделал это.
создать метод AddFunc(), способный использовать функции метода.
вариант № 3 действительно построен, но дополнительный AddFunc был бы лучше. проблема в том, что я не знаю, какой прототип метода предоставить. я думал, что TMethod подойдет, но мои знания здесь слишком ограничены ... вот моя неудачная попытка, но я все еще получаю «E2250 Нет перегруженной версии« AddFunc », которую можно вызвать с этими аргументами» в eval.AddFunc () вызов, как и раньше.
TFloat64MethodFunc = function(c:pointer): TFloat64;
procedure TEasyEvaluator.AddFunc(const AName: string; AFunc: TFloat64MethodFunc);
begin
FOwnContext.Add(TExprFloat64MethodFuncSym.Create(AName, AFunc));
end;
TExprFloat64MethodFuncSym = class(TExprAbstractFuncSym)
private
FFunc: TFloat64MethodFunc;
public
constructor Create(const AIdent: string; AFunc: TFloat64MethodFunc);
function Evaluate: TFloat; override;
// not using function Compile: TExprNode; override;
end;
Спасибо за помощь!
mp