예제 #1
0
        /// <summary>
        /// This method is for introspection of attributes, it should simply
        /// add the key/values this attribute holds to the given <see cref="IAttributeReflector"/>.
        ///
        /// <para/>The default implementation calls <see cref="IAttributeReflector.Reflect(Type, string, object)"/> for all
        /// non-static fields from the implementing class, using the field name as key
        /// and the field value as value. The <see cref="IAttribute"/> class is also determined by Reflection.
        /// Please note that the default implementation can only handle single-Attribute
        /// implementations.
        ///
        /// <para/>Custom implementations look like this (e.g. for a combined attribute implementation):
        /// <code>
        ///     public void ReflectWith(IAttributeReflector reflector)
        ///     {
        ///         reflector.Reflect(typeof(ICharTermAttribute), "term", GetTerm());
        ///         reflector.Reflect(typeof(IPositionIncrementAttribute), "positionIncrement", GetPositionIncrement());
        ///     }
        /// </code>
        ///
        /// <para/>If you implement this method, make sure that for each invocation, the same set of <see cref="IAttribute"/>
        /// interfaces and keys are passed to <see cref="IAttributeReflector.Reflect(Type, string, object)"/> in the same order, but possibly
        /// different values. So don't automatically exclude e.g. <c>null</c> properties!
        /// </summary>
        /// <seealso cref="ReflectAsString(bool)"/>
        public virtual void ReflectWith(IAttributeReflector reflector) // LUCENENET NOTE: This method was abstract in Lucene
        {
            Type clazz = this.GetType();
            LinkedList <WeakReference <Type> > interfaces = AttributeSource.GetAttributeInterfaces(clazz);

            if (interfaces.Count != 1)
            {
                throw UnsupportedOperationException.Create(clazz.Name + " implements more than one Attribute interface, the default ReflectWith() implementation cannot handle this.");
            }

            interfaces.First.Value.TryGetTarget(out Type interf);

            //problem: the interfaces list has weak references that could have expired already

            FieldInfo[] fields = clazz.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
            try
            {
                for (int i = 0; i < fields.Length; i++)
                {
                    FieldInfo f = fields[i];
                    if (f.IsStatic)
                    {
                        continue;
                    }
                    reflector.Reflect(interf, f.Name, f.GetValue(this));
                }
            }
            catch (Exception e) when(e.IsIllegalAccessException())
            {
                // this should never happen, because we're just accessing fields
                // from 'this'
                throw RuntimeException.Create(e);
            }
        }
예제 #2
0
        /// <summary>
        /// This method is for introspection of attributes, it should simply
        /// add the key/values this attribute holds to the given <see cref="IAttributeReflector"/>.
        ///
        /// <para/>The default implementation calls <see cref="IAttributeReflector.Reflect(Type, string, object)"/> for all
        /// non-static fields from the implementing class, using the field name as key
        /// and the field value as value. The <see cref="IAttribute"/> class is also determined by Reflection.
        /// Please note that the default implementation can only handle single-Attribute
        /// implementations.
        ///
        /// <para/>Custom implementations look like this (e.g. for a combined attribute implementation):
        /// <code>
        ///     public void ReflectWith(IAttributeReflector reflector)
        ///     {
        ///         reflector.Reflect(typeof(ICharTermAttribute), "term", GetTerm());
        ///         reflector.Reflect(typeof(IPositionIncrementAttribute), "positionIncrement", GetPositionIncrement());
        ///     }
        /// </code>
        ///
        /// <para/>If you implement this method, make sure that for each invocation, the same set of <see cref="IAttribute"/>
        /// interfaces and keys are passed to <see cref="IAttributeReflector.Reflect(Type, string, object)"/> in the same order, but possibly
        /// different values. So don't automatically exclude e.g. <c>null</c> properties!
        /// </summary>
        /// <seealso cref="ReflectAsString(bool)"/>
        public virtual void ReflectWith(IAttributeReflector reflector) // LUCENENET NOTE: This method was abstract in Lucene
        {
            Type clazz = this.GetType();
            LinkedList <WeakReference <Type> > interfaces = AttributeSource.GetAttributeInterfaces(clazz);

            if (interfaces.Count != 1)
            {
                throw new NotSupportedException(clazz.Name + " implements more than one Attribute interface, the default ReflectWith() implementation cannot handle this.");
            }

            interfaces.First.Value.TryGetTarget(out Type interf);

            //problem: the interfaces list has weak references that could have expired already

            FieldInfo[] fields = clazz.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
            try
            {
                for (int i = 0; i < fields.Length; i++)
                {
                    FieldInfo f = fields[i];
                    if (f.IsStatic)
                    {
                        continue;
                    }
                    reflector.Reflect(interf, f.Name, f.GetValue(this));
                }
            }
            catch (MemberAccessException e)
            {
                throw new Exception(e.ToString(), e);
            }
        }