如何编译方面的字符串条件

发布于 2024-12-25 06:02:31 字数 1331 浏览 1 评论 0原文

我有一个简单的课程。我必须为某些方法和属性添加一些条件。例如:

public class Example
{
  public Boolean Condition {get; set;}
  public Double ConditionValue {get; set;}

  [Verify("!Condition && ConditionValue>5")]
  public void DoSomthing()
  { ... }
}

我想检查方面属性中的条件(例如,“!Condition && ConditionValue>5”)。我无法将操作/功能赋予属性,因此我给出了一个简单的字符串。我需要将此字符串转换为一个条件:

[Serializable]
public class MyAspectAttribute : OnMethodBoundaryAspect
{
    public override void OnExit(MethodExecutionArgs args)
    {
        if (!this.Condition && this.ConditionValue>5) // If-statment from string, this is the problem...
        { ... }
    }
}  

How I can extract real if-statement from string?我看到一些解决方案,但我不确定它们是否有效:

  1. 使用运行时编译器,例如 CSharpCodeProvider。
  2. 使用诸如 http://flee.codeplex.com/ 这样的库
  3. 还有什么...?

我怎样才能优雅地做到这一点?谢谢!

更新:我已经编辑了建议中的问题...... Upd2:我尝试验证我的代码,我可以这样做:

public class Example2
    {
      public Boolean Condition {get; set;}

      [LoggingIf("Condition")]
      public void DoSomthing1()
      { ... }

      [PrintReportIf("!Condition")]
      public void DoSomthing2()
      { ... }
    }

I have a simple class. And I have to add some conditions to some methods and properties. For example:

public class Example
{
  public Boolean Condition {get; set;}
  public Double ConditionValue {get; set;}

  [Verify("!Condition && ConditionValue>5")]
  public void DoSomthing()
  { ... }
}

I want to check the condition (for example, "!Condition && ConditionValue>5") in an aspect attribute. I can not give an action/func into an attribute so I give a simple string. And I need to translate this string into a condition:

[Serializable]
public class MyAspectAttribute : OnMethodBoundaryAspect
{
    public override void OnExit(MethodExecutionArgs args)
    {
        if (!this.Condition && this.ConditionValue>5) // If-statment from string, this is the problem...
        { ... }
    }
}  

How I can extract real if-statment from string? I see some solutions, but I'm not sure they fine:

  1. Use a runtime compiler, e.g. CSharpCodeProvider.
  2. Use a library such as http://flee.codeplex.com/
  3. Somthing else...?

How I can do it gracefully? Thanks!

Upd: I have edited the question on the advices...
Upd2: I don't try to verification my code, I can do this:

public class Example2
    {
      public Boolean Condition {get; set;}

      [LoggingIf("Condition")]
      public void DoSomthing1()
      { ... }

      [PrintReportIf("!Condition")]
      public void DoSomthing2()
      { ... }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

似梦非梦 2025-01-01 06:02:31

考虑使用 lambda 表达式解析器?您应该能够执行以下操作:

[Verify("(Example e) => !e.Condition && e.Condition > 5")]
public void DoSomthing() 
{ ... }

并稍后使用以下命令进行编译:

[Serializable]
public class MyAspectAttribute : OnMethodBoundaryAspect
{
    public override void OnExit(MethodExecutionArgs args)
    {
         ExprParser parser = new ExprParser();
         LambdaExpression lambda = parser.Parse(/* Verify string comes here */);
         bool isConditionMet = (bool) parser.Run(lambda, this);

         if (isConditionMet)
         { ... }
    }
}

编辑:

对于自定义用户类型,您需要提供命名空间(如果类型驻留在与您调用的程序集不同的程序集中,则需要提供程序集)解析器):

ExprParser.Using.Add("PersonTypeNamespace");
ExprParser parser = new ExprParser();
LambdaExpression lambda = parser.Parse("(Person p) => p.Name");
var output = parser.Run(lambda, new Person { Name = "DragonFire" });

下载部分中有用户指南文件 -它提供了一些有关图书馆的额外信息 用法。

Considered using lambda expressions parser? You should be able to do something along the lines:

[Verify("(Example e) => !e.Condition && e.Condition > 5")]
public void DoSomthing() 
{ ... }

And compile that later using:

[Serializable]
public class MyAspectAttribute : OnMethodBoundaryAspect
{
    public override void OnExit(MethodExecutionArgs args)
    {
         ExprParser parser = new ExprParser();
         LambdaExpression lambda = parser.Parse(/* Verify string comes here */);
         bool isConditionMet = (bool) parser.Run(lambda, this);

         if (isConditionMet)
         { ... }
    }
}

Edit:

For custom user types, you need to provide namespace (and assembly if type resides in different assembly than the one you call parser from):

ExprParser.Using.Add("PersonTypeNamespace");
ExprParser parser = new ExprParser();
LambdaExpression lambda = parser.Parse("(Person p) => p.Name");
var output = parser.Run(lambda, new Person { Name = "DragonFire" });

In download section there's User guide file - it provides some extra information on library usage.

无敌元气妹 2025-01-01 06:02:31

创建一组实现布尔逻辑的对象。

  • 等于比较器(采用属性的名称和值)
  • 大于比较器(采用属性的名称和值)
  • 和比较器(采用两个比较器)
  • 布尔求值器(采用布尔属性的名称)
  • 等等,等等

然后有您的属性将这些对象之一作为参数

[Verify(new AndComparator(
    new BooleanEvaluator ("Condition"), 
    new GreaterThanComparator("ConditionValue", 5)))]
public void DoSomthing()

Create a set of objects that implements Boolean logic.

  • Equals Comparator (takes the name of a property and a value)
  • Greater Than Comparator (takes the name of a property and a value)
  • And Comparator (takes two comparators)
  • Boolean Evaluator (take the name of a boolean property)
  • etc, etc

Then have your attribute take one of these objects as a parameter

[Verify(new AndComparator(
    new BooleanEvaluator ("Condition"), 
    new GreaterThanComparator("ConditionValue", 5)))]
public void DoSomthing()
携君以终年 2025-01-01 06:02:31

查看代码合同:http://research.microsoft.com/en-us /projects/contracts/ 如果自定义属性不是必须的,它们可能正是您正在寻找的。

代码契约擅长定义对方法的允许参数和返回值的约束,并可选择在运行时(甚至编译时,尽管它确实会减慢 IDE 的速度)检查它们

Take a look at Code Contracts: http://research.microsoft.com/en-us/projects/contracts/ If having custom attributes is not a must, they may be just what you are looking for.

Code Contracts are good at defining constraints on permissable parameter and return values of methods and optionally checking them at run-time (and even compile time, though it really slows down the IDE)

别忘他 2025-01-01 06:02:31

您已经知道要使用的公式,因此只需将值传递给方面即可。

public class MyValidationAspect : OnMethodBoundaryAspect
{

public int Val1 { get; set; }
public int Val2 { get; set; }

public override void OnExit(MethodExecutionArgs args) 
    { 
        if (this.args.Arguments[0] > Val1) // If-statment from string, this is the problem... 
        { ... } 
    } 


}

[MyValidationAspect(Val1 = 5, Val2 = ...)]

不要尝试如此通用/动态,只需制定一组具体方面并根据需要传递值即可。

或者,您可以使用 Rosylen(编译器即服务)。

You already know the formula you want to use so just pass in the values to the aspect.

public class MyValidationAspect : OnMethodBoundaryAspect
{

public int Val1 { get; set; }
public int Val2 { get; set; }

public override void OnExit(MethodExecutionArgs args) 
    { 
        if (this.args.Arguments[0] > Val1) // If-statment from string, this is the problem... 
        { ... } 
    } 


}

[MyValidationAspect(Val1 = 5, Val2 = ...)]

Do not try to be so generic/dynamic just make a set of concrete aspects and pass in the values as needed.

Or, you can use Rosylen (Compiler as a Service).

梦醒灬来后我 2025-01-01 06:02:31

为什么不做这样的事情:

public class Example
{
  public Boolean Condition {get; set;}
  public Double ConditionValue {get; set;}


  public void DoSomthing()
  { 
           Verify.That(!Condition && ConditionValue>5);
           ...
  }
}

它的代码量几乎相同,它将在编译时进行编译和验证,您将能够将内容放入配置中,验证私有成员并进行复杂的验证。

Why not doing something like this:

public class Example
{
  public Boolean Condition {get; set;}
  public Double ConditionValue {get; set;}


  public void DoSomthing()
  { 
           Verify.That(!Condition && ConditionValue>5);
           ...
  }
}

It's almost the same amount of code, it will be compiled and validated in compile time, you will be able to put things in configuration, verify private members and do complex verifications.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文