Beispiel #1
0
            internal virtual T Or(T other)
            {
                if (!this.CanOr(other))
                {
                    return(default(T));
                }

                // start with a deep copy of this
                T result = this.Clone();

                // Or will only affect the collection properties since CanOr requires the non-collection properties to have equivalent values
                foreach (Tuple <PropertyInfo, ExpressionElementCollectionPropertyAttribute> tuple in this.ExpressionElementCollectionProperties)
                {
                    // Get property and attribute
                    PropertyInfo property = tuple.Item1;
                    ExpressionElementCollectionPropertyAttribute attribute = tuple.Item2;

                    // Get the value of the collection
                    object thisVal = property.GetValue(result, null);

                    // CanOr ensures that the collections are either both null or neither null so only one needs to be tested
                    if (thisVal != null)
                    {
                        object otherVal = property.GetValue(other, null);

                        // Find Union function and invoke to get the union
                        object union = attribute.InvokeUnionMethod(new[] { thisVal, otherVal });

                        // set the union value on the copy (result)
                        property.SetValue(result, union, null);
                    }
                }

                return(result);
            }
Beispiel #2
0
            internal virtual T And(T other)
            {
                // start with a deep copy both elements
                T result = this.Clone();

                other = other.Clone();

                // for AND, the non-collection properties cannot conflict
                foreach (PropertyInfo property in this.ExpressionElementProperties)
                {
                    // Get values
                    var thisVal  = property.GetValue(result, null);
                    var otherVal = property.GetValue(other, null);

                    // if other has a constraint
                    if (otherVal != null)
                    {
                        // AND this has a constraint
                        if (thisVal != null)
                        {
                            // then they must be the same
                            if (!object.Equals(thisVal, otherVal))
                            {
                                return(default(T));
                            }
                        }
                        else
                        {
                            // other has one, but this doesn't simply add the constraint
                            property.SetValue(result, otherVal, null);
                        }
                    }
                }

                // for the collection properties, the result will have the intersection
                foreach (Tuple <PropertyInfo, ExpressionElementCollectionPropertyAttribute> tuple in this.ExpressionElementCollectionProperties)
                {
                    // Get property and attribute
                    PropertyInfo property = tuple.Item1;
                    ExpressionElementCollectionPropertyAttribute attribute = tuple.Item2;

                    // Get values
                    var thisVal  = property.GetValue(result, null);
                    var otherVal = property.GetValue(other, null);

                    // if other has a constraint
                    if (otherVal != null)
                    {
                        // Take other's constraint in the absence of one on this, otherwise take the intersection
                        if (thisVal == null)
                        {
                            property.SetValue(result, otherVal, null);
                        }
                        else
                        {
                            // Find Intersect function and invoke to get the intersection
                            object intersect = attribute.InvokeIntersectMethod(new[] { thisVal, otherVal });

                            property.SetValue(result, intersect, null);
                        }
                    }
                }

                return(result);
            }