Если вы хотите сохранить своего делегата в качестве выражения, вы можете достичь того, чего хотите. Код будет выглядеть примерно так:
private Expression<Func<double, double>> myFunc;
private Func<double, double> cachedDelegate;
public void SetFunc(Expression<Func<double,double>> newFunc)
{
this.myFunc = newFunc;
this.cachedDelegate = null;
}
public double ExecFunc(double x)
{
if (this.myFunc != null)
{
if (this.cachedDelegate != null)
{
return this.cachedDelegate(x);
}
else
{
this.cachedDelegate = this.myFunc.Compile();
return this.cachedDelegate(x);
}
}
return 0.0;
}
public string GetFuncText()
{
if (this.myFunc != null)
{
return this.myFunc.ToString();
}
return "";
}
Чтобы реально использовать лямбда-выражение, сначала нужно скомпилировать его. Хранение его в делегате означает, что вы получаете этот удар только один раз.
Кроме того, этот подход означает, что пользователи должны использовать лямбду, поскольку группы методов не могут быть преобразованы в Expression<Func<>>
. Это не большая проблема, поскольку вместо передачи MyMethod
пользователь может передать x => MyMethod(x)
.
Код вызова будет выглядеть примерно так:
myObject.SetFunc(x => 2*x);
Console.WriteLine(myObject.GetFuncText());
И последнее замечание: приведенный выше пример не является потокобезопасным, поэтому, если вы ожидаете, что методы будут вызываться из нескольких потоков, будет уместна какая-то синхронизация.