C# 转换字符串以用于逻辑条件
Posted
技术标签:
【中文标题】C# 转换字符串以用于逻辑条件【英文标题】:C# convert a string for use in a logical condition 【发布时间】:2010-10-29 21:07:06 【问题描述】:是否可以将字符串转换为运算符以用于逻辑条件。
例如
if(x Convert.ToOperator(">") y)
或
if(x ">" as Operator y)
我明白这可能不是标准练习问题,因此我对那些问我为什么要这样做的答案不感兴趣。
提前致谢
编辑:好的,我同意,只是提供一些背景信息。
我们有围绕反射和 XML 构建的系统。为了方便起见,我希望能够说一些类似的话。
<Value = "Object1.Value" Operator = ">" Condition = "0"/>
编辑:感谢您的 cmets,我无法在此处正确解释这一点。我想我的问题得到了“你不能”的回答,这绝对没问题(和我想的一样)。感谢您的 cmets。
编辑:草草了,我要试一试。
想象一下
<Namespace.LogicRule Value= "Object1.Value" Operator=">" Condition="0">
这将反映到一个类中,所以现在我想通过调用来测试条件
bool LogicRule.Test()
这就是所有需要结合在一起的地方。
编辑:
好的,所以我从来没有看过 Lambdas 或 Expressions,我想我会看看 @jrista 的建议。
我的系统允许解析枚举,因此表达式很有吸引力,因为表达式类型枚举。
所以我创建了以下类来测试这个想法:
public class Operation
private object _Right;
private object _Left;
private ExpressionType _ExpressionType;
private string _Type;
public object Left
get return _Left;
set _Left = value;
public object Right
get return _Right;
set _Right = value;
public string Type
get return _Type;
set _Type = value;
public ExpressionType ExpressionType
get return _ExpressionType;
set _ExpressionType = value;
public bool Evaluate()
var param = Expression.Parameter(typeof(int), "left");
var param2 = Expression.Parameter(typeof(int), "right");
Expression<Func<int, int, bool>> expression = Expression.Lambda<Func<int, int, bool>>(
Expression.MakeBinary(ExpressionType, param, param2), param, param2);
Func<int, int, bool> del = expression.Compile();
return del(Convert.ToInt32(Left), Convert.ToInt32(Right));
显然,这仅适用于 Int32 现在和基本的 ExpressionTypes,我不确定我是否可以使其通用?我以前从未使用过表达式,但这似乎可行。
这种方式可以在我们的 XML 方式中声明为
Operation<Left="1" Right="2" ExpressionType="LessThan" Type="System.Int32"/>
【问题讨论】:
我不会回答“你为什么要这样做”,但我会评论它:)。不是想成为痛苦,我只是好奇为什么这对您的应用程序很重要。 @JaredPar:我经常看到这种情况:人们希望将其存储在数据库中并检索它以供以后在代码中使用。并不意味着这是一个好主意,但这就是它的来源。 感谢您的更新,但您想用该 XML 做什么,它是什么意思?是否要在元素“q”中包含该示例,并根据 XML 元素中表示的条件执行“if (Compare(q,x))”以比较变量“x”? @JaredPar:作为旁注,这是 OperatorCache你可以这样做:
public static bool Compare<T>(string op, T x, T y) where T:IComparable
switch(op)
case "==" : return x.CompareTo(y)==0;
case "!=" : return x.CompareTo(y)!=0;
case ">" : return x.CompareTo(y)>0;
case ">=" : return x.CompareTo(y)>=0;
case "<" : return x.CompareTo(y)<0;
case "<=" : return x.CompareTo(y)<=0;
【讨论】:
【参考方案2】:编辑
正如 JaredPar 指出的那样,我在下面的建议不起作用,因为您不能将运算符应用于泛型...
因此,您需要为要比较/计算的每种类型都有特定的实现......
public int Compute (int param1, int param2, string op)
switch(op)
case "+": return param1 + param2;
default: throw new NotImplementedException();
public double Compute (double param1, double param2, string op)
switch(op)
case "+": return param1 + param2;
default: throw new NotImplementedException();
ORIG
你可以这样做。
您还需要尝试/捕获所有这些以确保无论 T 是什么,都支持特定操作。
请注意,如果我问您为什么可能需要这样做。你在写某种数学解析器吗?
public T Compute<T> (T param1, T param2, string op) where T : struct
switch(op)
case "+":
return param1 + param2;
default:
throw new NotImplementedException();
public bool Compare<T> (T param1, T param2, string op) where T : struct
switch (op)
case "==":
return param1 == param2;
default:
throw new NotImplementedException();
【讨论】:
会编译吗?我不这么认为。 虽然这是一种非常有限的方法。在 == 和 != 之外,您不能对通用值使用运算符。 @John,可能不是,我直接在 SO 窗口中乱写了它,所以它是半伪 @Jared。真的吗 ?好的...划掉那个想法... :(【参考方案3】:不,这是不可能的,你为什么要这么做?
当然,您可以创建如下函数:
public static bool Compare<T>(char op, T a, T b);
【讨论】:
“op”可能需要多于一个字符;您可以将“!=”或“”或“==”作为潜在的运算符。【参考方案4】:您应该考虑使用 .NET 3.5 的表达式树。您可以手动将表达式构建到表达式树(基本上是 AST)中,然后调用 Expression.Compile() 来创建可调用委托。您的 LogicRule.Test() 方法需要构建表达式树,将树包装在 LambdaExpression 中,LambdaExpression 将您应用规则的对象也作为参数,调用 Compile(),并调用生成的委托。
【讨论】:
【参考方案5】:我在以下人员的帮助下做了类似的事情:
http://flee.codeplex.com/
这个工具基本上可以评估各种表达式。基本用法是传入像 '3 > 4' 这样的字符串,该工具将返回 false。
不过,你也可以创建一个求值器的实例并传入对象名称/值对,它可以更直观一点 IE:myObject^7
您可以在 codeplex 网站上深入了解更多功能。
【讨论】:
【参考方案6】:<Function = "PredicateMore" Param1 = "Object1.Value" Param2 = "0"/>
【讨论】:
【参考方案7】:我认为您可以使用implicit casting 来实现这一点。比如:
public static implicit operator Operator(string op)
switch(op)
case "==" :
return new EqualOperator();
...
Operator op = "<";
if( op.Compare(x,y) ) ...
//or whatever use syntax you want for Operator.
【讨论】:
【参考方案8】:Vici Parser(开源)可能对您有所帮助。这是一个 C# 表达式解析器,您可以在其中传递一个包含表达式的字符串,然后返回计算结果。
【讨论】:
【参考方案9】:您可以为此使用 DynamicLinq:
void Main()
var match = OpCompare(6, ">=", 4);
match.Dump();
private bool OpCompare<T>(T leftHand, string op, T rightHand)
return new List<T>() leftHand .AsQueryable().Where($"it op rightHand").Any();
【讨论】:
以上是关于C# 转换字符串以用于逻辑条件的主要内容,如果未能解决你的问题,请参考以下文章
Json反序列化器或正则表达式或Json解析以在c#中转换Json字符串