นี่เป็นเวอร์ชันดั้งเดิมของปัญหาดั้งเดิม
ฉันมีชั้นเรียนที่เรียกว่าบุคคล:
public class Person {
public string Name { get; set; }
public int Age { get; set; }
public int Weight { get; set; }
public DateTime FavouriteDay { get; set; }
}
... และให้พูดตัวอย่าง:
var bob = new Person {
Name = "Bob",
Age = 30,
Weight = 213,
FavouriteDay = '1/1/2000'
}
ฉันต้องการเขียนข้อความต่อไปนี้เป็นสตริงในโปรแกรมแก้ไขข้อความที่ชื่นชอบ ....
(Person.Age > 3 AND Person.Weight > 50) OR Person.Age < 3
ฉันต้องการใช้สตริงนี้และอินสแตนซ์ของวัตถุและประเมินค่า TRUE หรือ FALSE - เช่นการประเมิน Func <Person, bool> บนอินสแตนซ์ของวัตถุ
นี่คือความคิดปัจจุบันของฉัน:
- ใช้ไวยากรณ์พื้นฐานใน ANTLR เพื่อสนับสนุนการเปรียบเทียบและผู้ประกอบการทางตรรกะขั้นพื้นฐาน ฉันกำลังคิดว่าจะคัดลอกลำดับความสำคัญของ Visual Basic และชุดฟีเจอร์บางส่วนที่นี่: http://msdn.microsoft.com/en-us/library/fw84t893(VS.80).aspx
- ให้ ANTLR สร้าง AST ที่เหมาะสมจากสตริงที่จัดเตรียม
- เดิน AST และใช้เฟรมเวิร์กPredicate Builderเพื่อสร้าง Func <Person, bool> แบบไดนามิก
- ประเมินเพรดิเคตกับอินสแตนซ์ของบุคคลตามที่ต้องการ
คำถามของฉันคือฉัน overbaked ทั้งหมดนี้หรือไม่ ทางเลือกใด ๆ
แก้ไข: Chosen Solution
ฉันตัดสินใจใช้ Dynamic Linq Library โดยเฉพาะคลาส Dynamic Query ที่ให้ไว้ใน LINQSamples
รหัสด้านล่าง:
using System;
using System.Linq.Expressions;
using System.Linq.Dynamic;
namespace ExpressionParser
{
class Program
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public int Weight { get; set; }
public DateTime FavouriteDay { get; set; }
}
static void Main()
{
const string exp = @"(Person.Age > 3 AND Person.Weight > 50) OR Person.Age < 3";
var p = Expression.Parameter(typeof(Person), "Person");
var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, exp);
var bob = new Person
{
Name = "Bob",
Age = 30,
Weight = 213,
FavouriteDay = new DateTime(2000,1,1)
};
var result = e.Compile().DynamicInvoke(bob);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
ผลลัพธ์เป็นชนิด System.Boolean และในกรณีนี้คือ TRUE
ขอบคุณ Marc Gravell
รวมSystem.Linq.Dynamicแพ็คเกจแพคเกจเอกสารที่นี่