尝试在线搜索但到目前为止没有运气
基本上我允许用户创建一个选择表达式,例如
TargetHealthLessThen20 TargetAboutToUsePotion
这些是针对枚举存储的,然后作为字符串表达式存储在数据库中,例如
" TargetHealthLessThen20 || TargetAboutToUsePotion"
现在我有每个枚举的方法来检查它的条件,即
public bool IsTargetHealthLessThen20(Target target)
{
// do login
}
public bool IsTargetAboutToUsePotion(Target target)
{
// do login
}
我希望能够编写一个动态的If语句来调用这些方法并放入条件,例如
if("IsTargetHealthLessThen20(target) || IsTargetAboutToUsePotion(target)")
{
// Perform Action
}
关于最佳解决方法的任何想法?
答案 0 :(得分:1)
虽然由于性能原因我不一定会推荐以下内容,但它会做你想要的。
如果你总是应用你的目标而只是你的目标,你可以预先定义一类评估方法,然后传入一个字符串方法名称列表来评估这些方法。
void Main()
{
var inputs = new List<string>();
inputs.Add("MethodA");
inputs.Add("MethodB");
var results = Evaluate(inputs, "target");
Console.WriteLine(results);
}
public bool Evaluate(List<string> predicates, string target)
{
var methods = new Methods();
var tempResult = false;
foreach (var pred in predicates)
{
var method = methods.GetType().GetMethod(pred);
if (method == null)
throw new InvalidOperationException(
string.Format("Unknown method {0}.", pred));
tempResult = (bool)typeof(Methods).GetMethod(pred).Invoke(methods, new [] {target});
if (!tempResult) break;
continue;
}
return tempResult;
}
public class Methods
{
public bool MethodA(string target)
{
return target == "target";
}
public bool MethodB(string target)
{
return target == "not a target";
}
}
此特定评估功能将评估AND条件。您需要更改OR条件的评估逻辑。理论上,您可以检查字符串并根据字符串中的运算符调用不同的方法。
修改强>
避免反射的第二个选项是创建一个Dictionary,将您的方法的字符串名称映射到方法本身。这将允许您在没有反射的情况下实现相同的结果,尽管您必须保持字典同步。另一方面,您可以获得额外的编译时检查而无需反射开销。
private static readonly Methods _methodsInstance = new Methods();
private static Dictionary<string, Func<string, bool>> _methods = new Dictionary<string, Func<string, bool>>()
{
{ "MethodA", _methodsInstance.MethodA },
{ "MethodB", _methodsInstance.MethodB },
};
public bool Evaluate(List<string> predicates, string target)
{
var tempResult = false;
foreach (var pred in predicates)
{
tempResult = _methods[pred](target);
if (!tempResult) break;
continue;
}
return tempResult;
}
答案 1 :(得分:0)
我认为这是困难的。因为您不知道目标参数值。如果你知道参数值,你可以使用reflect通过表达式字符串调用方法。
答案 2 :(得分:0)
我想我只有你正在寻找的答案,因为我过去几乎需要完全相同的事情:
你所拥有的是C#代码,所以你需要像对待它一样对待它:)
创建一个类似
的界面 interface ICondition { bool Evaluate(); }
现在使用您在那里的文本将其编译成一个类。
像这样:
using YourProgramNamespace;
class myCondition : ICondition
{
bool Evaluate() { return {0} ; }
}
要传递更多参数,只需更改接口以允许匹配参数。
如果您不想要多个接口,请按以下方式进行:
using YourProgramNamespace;
class myCondition : ICondition
{
bool Evaluate(params object[] parameters) { return {0} ; }
}
在你的文本中,你只需这样写:
TargetHasLessThan20Hp((TargetType的)参数[0])
将{0}替换为您已有的条件文本。
使用C#编译器编译代码。 http://msdn.microsoft.com/de-de/library/microsoft.csharp.csharpcodeprovider%28v=vs.110%29.aspx 有关如何使用它的教程绰绰有余,而且它的用法并不那么难。
当您将类编译成Dll加载它并找到带反射的类型时,这也不难,并且有大量的教程。只需使用yourAssembly.GetTypes()并从那里开始
使用Activator.CreateInstance实例化您拥有的类型
然后只需调用evaluate函数,它将返回true或false。
为了获得更好的性能,请不要每次编译,直到条件文本实际发生变化。
需要更多信息?只需询问,我就会编辑我的答案或在评论中发布。