/// <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); } }
/// <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); } }