Esempio n. 1
0
        protected override Expression BuildSerializerSafe(Expression encoder, Expression value)
        {
            // Indexing schemas according to their position.
            // according to avro spec http://avro.apache.org/docs/current/spec.html#Unions
            // Unions may not contain more than one schema with the same type, except for the named types record, fixed and enum.
            // For example, unions containing two array types or two map types are not permitted, but two types with different names are permitted
            int schemaIndex = 0;

            var schemas = new List <IndexedSchema>(this.itemSchemas.Count);

            foreach (var typeSchema in this.itemSchemas)
            {
                // use FirstOrDefault rather than SingleOrDefault because we need to add all schema to the list.
                var existingSchema = schemas.FirstOrDefault(s => UnionSchema.IsSameTypeAs(s.Schema, typeSchema));
                var index          = existingSchema != null ? existingSchema.Index : schemaIndex++;
                var indexSchema    = new IndexedSchema {
                    Schema = typeSchema, Index = index
                };
                schemas.Add(indexSchema);
            }

            // Nullable schemas.
            if (schemas.Count == 2 && schemas.Select(s => s.Schema).OfType <NullSchema>().Any())
            {
                return(this.BuildNullableSerializer(encoder, value, schemas));
            }

            // Sort according to inheritance hierarchy - most specialized type goes first.
            schemas.Sort(this.MoreSpecializedTypesFirst);
            return(this.BuildUnionSerializer(encoder, value, schemas));
        }
Esempio n. 2
0
        private int MoreSpecializedTypesFirst(IndexedSchema s1, IndexedSchema s2)
        {
            if (s1.Schema.RuntimeType.IsAssignableFrom(s2.Schema.RuntimeType))
            {
                return(1);
            }

            if (s2.Schema.RuntimeType.IsAssignableFrom(s1.Schema.RuntimeType))
            {
                return(-1);
            }

            return(s1.Index.CompareTo(s2.Index));
        }