lucenenet-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Andy Pook (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (LUCENENET-469) Convert Java Iterator classes to implement IEnumerable<T>
Date Tue, 08 Aug 2017 19:13:00 GMT

    [ https://issues.apache.org/jira/browse/LUCENENET-469?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16118872#comment-16118872
] 

Andy Pook commented on LUCENENET-469:
-------------------------------------

How about something like...

{code}
	public abstract class TermEnum : IEnumerable<TermFreq>, IDisposable
	{
		public abstract bool Next();
		public abstract Term Term();
		public abstract int DocFreq();
		public abstract void Close();
		public abstract void Dispose();

		public IEnumerator<TermFreq> GetEnumerator() => new EnumEnumerator<TermFreq>(Next,
Dispose, () => new TermFreq { Term = Term(), DocFreq = DocFreq() });

		IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
	}

	public class TermFreq
	{
		public Term Term { get; set; }
		public int DocFreq { get; set; }
	}

	public class EnumEnumerator<T> : IEnumerator<T>
	{
		private readonly Func<bool> next;
		private readonly Action dispose;
		private readonly Func<T> currentFactory;

		private bool started = false;

		public EnumEnumerator(Func<bool> next, Action dispose, Func<T> currentFactory)
		{
			this.next = next;
			this.dispose = dispose;
			this.currentFactory = currentFactory;
		}

		public T Current => started ? currentFactory() : default(T);

		object IEnumerator.Current => Current;

		public bool MoveNext() => (started = next());

		public void Reset() => throw new NotImplementedException();

		public void Dispose() => dispose();
	}
{code}

Excuse the c#7 lambda stuff, just used for brevity. Would expand if theory accepted.

The idea is to have a default generic Enumerator which can be used for any Iterator type.
So, simply add the IEnumerable i/f and the two GetEnumerator methods returning the generic.
It takes Next, Dispose and a factory to create the items.
The started member is to emulate the enumerator semantic of being null before the first call
to MoveNext.
Enum's aren't resetable so just throw?
In this example I've kept the item type simple. But it would probably be implemented as an
immutable.

Observation: There don't seem to be many Enum types (those that have {{bool Next()}}) I'm
assuming other have already been converted?

Thoughts?

> Convert Java Iterator classes to implement IEnumerable<T>
> ---------------------------------------------------------
>
>                 Key: LUCENENET-469
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-469
>             Project: Lucene.Net
>          Issue Type: Sub-task
>          Components: Lucene.Net Contrib, Lucene.Net Core
>    Affects Versions: Lucene.Net 2.9.4, Lucene.Net 2.9.4g, Lucene.Net 3.0.3, Lucene.Net
4.8.0
>         Environment: all
>            Reporter: Christopher Currens
>             Fix For: Lucene.Net 4.8.0
>
>
> The Iterator pattern in Java is equivalent to IEnumerable in .NET.  Classes that were
directly ported in Java using the Iterator pattern, cannot be used with Linq or foreach blocks
in .NET.
> {{Next()}} would be equivalent to .NET's {{MoveNext()}}, and in the below case, {{Term()}}
would be as .NET's {{Current}} property.  In cases as below, it will require {{TermEnum}}
to become an abstract class with {{Term}} and {{DocFreq}} properties, which would be returned
from another class or method that implemented {{IEnumerable<TermEnum>}}.
> {noformat} 
> 	public abstract class TermEnum : IDisposable
> 	{
> 		public abstract bool Next();
> 		public abstract Term Term();
> 		public abstract int DocFreq();
> 		public abstract void  Close();
> 	        public abstract void Dispose();
> 	}
> {noformat} 
> would instead look something like:
> {noformat} 
> 	public class TermFreq
> 	{
> 		public abstract Term { get; }
> 		public abstract int { get; }
> 	}
>         public abstract class TermEnum : IEnumerable<TermFreq>, IDisposable
>         {
>                 // ...
>         }
> {noformat}
> Keep in mind that it is important that if the class being converted implements {{IDisposable}},
the class that is enumerating the terms (in this case {{TermEnum}}) should inherit from both
{{IEnumerable<T>}} *and* {{IDisposable}}.  This won't be any change to the user, as
the compiler automatically calls {{IDisposable}} when used in a {{foreach}} loop.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Mime
View raw message