序列化逻辑表达式的结构

时间:2011-08-02 16:46:10

标签: c# wcf

我需要将一个逻辑表达式列表传递给WCF服务,具体如下:

[0] (A & B) || (C & D)
[1] (E || F)
[2] G

以上是三个元素的示例列表,每个元素描述一个包含AND,OR和分组的布尔表达式。条件(A,B,C,D,E,F,G)中的项目都是相同类型的实体。

是否只是使用字符串的最佳方法,并在收到消息时在服务器上解析它们,或者是否可以使用类结构/层次结构?我很难想到如何将分组和布尔条件建模为类结构。

现实世界的目标是为将批准或拒绝已发布文档的多级用户建模。当满足列表中第一个元素表示的条件时,将通知下一级别的用户需要输入。这种情况一直持续到所有条件都已经过评估。

1 个答案:

答案 0 :(得分:1)

这两个选项(使用字符串和数据结构)都可以正常工作 - 它只取决于您希望将表达式转换为字符串以通过线路传输(这可能会导致较小的消息大小)或传输数据直接结构(线径可能更大,但您将在客户端和服务器之间共享相同的表达式树。)

下面的代码显示了您拥有的示例的一种可能的数据结构 - 树(它当前是二进制的,但不一定是这样)。

public class StackOverflow_6915554
{
    [DataContract]
    [KnownType(typeof(LeafExpression))]
    [KnownType(typeof(BinaryExpression))]
    public class Expression
    {
    }

    [DataContract]
    public class LeafExpression : Expression
    {
        [DataMember]
        public string Name;
    }

    [DataContract]
    public class BinaryExpression : Expression
    {
        [DataMember]
        public BinaryOperator Operator;
        [DataMember]
        public Expression Left;
        [DataMember]
        public Expression Right;
    }

    public enum BinaryOperator
    {
        And,
        Or,
    }

    public static void Test()
    {
        List<Expression> expressions = new List<Expression>();
        expressions.Add(new BinaryExpression
        {
            Left = new BinaryExpression
            {
                Left = new LeafExpression { Name = "A" },
                Operator = BinaryOperator.And,
                Right = new LeafExpression { Name = "B" },
            },
            Operator = BinaryOperator.Or,
            Right = new BinaryExpression
            {
                Left = new LeafExpression { Name = "C" },
                Operator = BinaryOperator.And,
                Right = new LeafExpression { Name = "D" },
            }
        });

        expressions.Add(new BinaryExpression
        {
            Left = new LeafExpression { Name = "E" },
            Operator = BinaryOperator.Or,
            Right = new LeafExpression { Name = "F" }
        });

        expressions.Add(new LeafExpression { Name = "G" });

        XmlWriterSettings ws = new XmlWriterSettings
        {
            Indent = true,
            IndentChars = "  ",
            Encoding = new UTF8Encoding(false),
            OmitXmlDeclaration = true,
        };

        MemoryStream ms = new MemoryStream();
        XmlWriter w = XmlWriter.Create(ms, ws);

        DataContractSerializer dcs = new DataContractSerializer(typeof(List<Expression>));
        dcs.WriteObject(w, expressions);
        w.Flush();

        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
    }
}