Exemplo n.º 1
0
        internal ClassDataContract(Type type) : base(type)
        {
            object[] dataContractAttributes;
            bool     hasDataContract;
            string   name = null, ns = null;

            if (type.IsSerializable)
            {
                if (type.IsDefined(Globals.TypeOfDataContractAttribute, false))
                {
                    throw new Exception(String.Format("Type {0} has both [Serializable] and [DataContract]", type.FullName));
                }
                hasDataContract = false;
                GetStableName(null, out name, out ns);
            }
            else
            {
                dataContractAttributes = type.GetCustomAttributes(Globals.TypeOfDataContractAttribute, false);
                if (dataContractAttributes != null && dataContractAttributes.Length > 0)
                {
                    if (dataContractAttributes.Length > 1)
                    {
                        throw new Exception(String.Format("Type {0} has more than one [DataContract] attribute", type.FullName));
                    }

                    hasDataContract = true;
                    DataContractAttribute dataContractAttribute = (DataContractAttribute)dataContractAttributes[0];
                    GetStableName(dataContractAttribute, out name, out ns);
                }
                else
                {
                    throw new Exception("Type has neither Serializable nor DataContract");
                }
            }

            this.StableName = new XmlQualifiedName(name, ns);

            if (type.BaseType != null && type.BaseType != Globals.TypeOfObject && type.BaseType != Globals.TypeOfValueType)
            {
                this.BaseContract = (ClassDataContract)DataContract.GetDataContract(type.BaseType);
            }
            else
            {
                this.BaseContract = null;
            }
            ImportDataMembers(type, hasDataContract);
        }
Exemplo n.º 2
0
        internal ArrayDataContract(Type type) : base(type)
        {
            rank = type.GetArrayRank();
            Type   elementType   = type;
            string arrayOfPrefix = String.Empty;

            while (elementType.IsArray)
            {
                arrayOfPrefix += "ArrayOf";
                elementType    = elementType.GetElementType();
            }

            DataContract elementDataContract = DataContract.GetDataContract(elementType);
            string       name = arrayOfPrefix + elementDataContract.StableName.Name;
            string       ns   = elementDataContract is PrimitiveDataContract ? Globals.SerializationNamespace : elementDataContract.StableName.Namespace;

            this.StableName = new XmlQualifiedName(name, ns);
        }
Exemplo n.º 3
0
        private bool CompareObjects(object lhObj, object rhObj)
        {
            if (lhObj == null && rhObj == null)
            {
                return(true);
            }

            if (lhObj == null || rhObj == null)
            {
                return(false);
            }

            Type lhObjType = lhObj.GetType();
            Type rhObjType = rhObj.GetType();

            //both objects have same circular reference
            if (lhsObjectHashTable[lhObj] != null && rhsObjectHashTable[rhObj] != null)
            {
                return(true);
            }
            // one object has circular ref, so not equal
            else if (lhsObjectHashTable[lhObj] != null || rhsObjectHashTable[rhObj] != null)
            {
                return(false);
            }

            DataContract lhDataContract = DataContract.GetDataContract(lhObjType);
            DataContract rhDataContract = DataContract.GetDataContract(rhObjType);

            //if either type is not serializable or DC, then above GetDataContract would throw
            //so both DataContracts are not null now
            if (!lhDataContract.Equals(rhDataContract))
            {
                return(false);
            }

            //lhDataContract and rhDataContract have same qname now (that's the Equals compare
            //enum, primitive, string and decimal can be compared by .Equals, note decimal is not a primitive
            //in this case, lhObjType should be equal to rhObjType
            if (lhObjType.IsEnum || lhObjType == typeof(Decimal) || lhObjType.IsPrimitive || lhObj is string)
            {
                System.Diagnostics.Debug.Assert(lhObjType == rhObjType, "types must be same for the compared objects when they are enum/primitive/string/decimal", string.Format("left type is {0}, right type is {1}", lhObjType, rhObjType));
                return(lhObj.Equals(rhObj));
            }
            else if (lhObjType.IsArray && rhObjType.IsArray)
            {
                Array lhArray = (Array)lhObj;
                Array rhArray = (Array)rhObj;

                if (lhArray.Length != rhArray.Length)
                {
                    return(false);
                }

                //indeces and bounds of the array to be compared
                //indeces is the current position
                Array indeces = Array.CreateInstance(typeof(int), lhArray.Rank);

                //bounds is the upper bounds of the array
                Array bounds           = Array.CreateInstance(typeof(int), lhArray.Rank);
                int   arrayTotalLength = 0;

                for (int i = 0; i < indeces.Length; i++)
                {
                    indeces.SetValue(0, i);
                    bounds.SetValue(lhArray.GetLength(i), i);
                    if (i == 0)
                    {
                        arrayTotalLength = lhArray.GetLength(0);
                    }
                    else
                    {
                        arrayTotalLength *= (int)lhArray.GetLength(i);
                    }
                }

                int  index  = 0;
                bool notEnd = true;

                //UNDONE: only need one condition, use both to double check here
                while (index < arrayTotalLength && notEnd)
                {
                    if (!this.CompareObjects(lhArray.GetValue((int[])indeces), rhArray.GetValue((int[])indeces)))
                    {
                        return(false);
                    }

                    //increase array indeces to the next element in the array
                    //always increment from the highest dimension
                    notEnd = this.IncIndex((int[])indeces, (int[])bounds, indeces.Length - 1);
                    index++;
                }

                return(true);
            }
            else
            {
                lhsObjectHashTable.Add(lhObj, lhObj);
                rhsObjectHashTable.Add(rhObj, rhObj);

                ClassDataContract lhClassDataContract = lhDataContract as ClassDataContract;
                ClassDataContract rhClassDataContract = rhDataContract as ClassDataContract;

                if (rhClassDataContract == null || lhClassDataContract == null)
                {
                    throw new Exception("type mismatch! not both are class/struct");
                }

                return(CompareDM(lhObj, lhClassDataContract, rhObj, rhClassDataContract));
            }
        }