internal VowpalWabbitSerializer(Func <TExample, IVowpalWabbitExample> serializer, VowpalWabbitSerializerSettings settings)
        {
            this.serializer = serializer;
            this.settings   = settings ?? new VowpalWabbitSerializerSettings();

            var cacheableAttribute = (CacheableAttribute)typeof(TExample).GetCustomAttributes(typeof(CacheableAttribute), true).FirstOrDefault();

            if (cacheableAttribute == null)
            {
                return;
            }

            if (this.settings.EnableExampleCaching)
            {
                if (cacheableAttribute.EqualityComparer == null)
                {
                    this.exampleCache = new Dictionary <TExample, VowpalWabbitCachedExample <TExample> >();
                }
                else
                {
                    if (!typeof(IEqualityComparer <TExample>).IsAssignableFrom(cacheableAttribute.EqualityComparer))
                    {
                        throw new ArgumentException(
                                  string.Format(
                                      CultureInfo.InvariantCulture,
                                      "EqualityComparer ({1}) specified in [Cachable] of {0} must implement IEqualityComparer<{0}>",
                                      typeof(TExample),
                                      cacheableAttribute.EqualityComparer));
                    }

                    var comparer = (IEqualityComparer <TExample>)Activator.CreateInstance(cacheableAttribute.EqualityComparer);
                    this.exampleCache = new Dictionary <TExample, VowpalWabbitCachedExample <TExample> >(comparer);
                }
            }
        }
        public static VowpalWabbitSerializer <TExample> CreateSerializer <TExample>(VowpalWabbitInterfaceVisitor visitor, VowpalWabbitSerializerSettings settings)
        {
            var serializerFunc = CreateSerializer <TExample, VowpalWabbitInterfaceVisitor, VowpalWabbitExample>();

            if (serializerFunc == null)
            {
                // if no features are found, no serializer is generated
                serializerFunc = (_, __) => null;
            }

            return(new VowpalWabbitSerializer <TExample>(ex => serializerFunc(ex, visitor), settings));
        }