Im not against breaking compatibility when changing the version number to a new major 2 -> 3. Im not sure how others feel. Matching Java access modifiers seems like the right move.
That said, what if we mark obsolete in 3.0.3 and when we make the jump to 4.0 wipe them out? In my head we shouldn't spend too much time cleaning up 3.0.3 aside from bug fixes if were just going to swap it for 4.0 in the near future. There has to be a break at some point, making it with a major release is the best place to make it. Sent from my Windows Phone ________________________________ From: Christopher Currens Sent: 2/24/2012 2:45 PM To: lucene-net-dev@lucene.apache.org Subject: [Lucene.Net] Official stance on API changes between major versions A bit of background about what I've been doing lately on the project. Because we've now confirmed that the .NET 3.0.3 branch is a completed port of Java 3.0.3 version, I've been spending time trying to work on some of the bugs and improvements that are assigned to this version. There wasn't any real discussion about the actual features, I just created some (based on mailing list discussions) and assigned them to the 3.0.3 release. The improvements I've been working on lately are ones that have bugged me specifically since I've started using Lucene.NET. I've worked on https://issues.apache.org/jira/browse/LUCENENET-468 and https://issues.apache.org/jira/browse/LUCENENET-470 so far. LUCENENET-740 is pretty much completed, all of the classes that implemented Closeable() now implement IDisposable, having a public void Dispose() and/or protected virtual void Dispose(bool disposing), depending if the class is sealed or not. What is left to do on that issue would be to make sure that all of the tests are a) overriding the protected dispose method as needed and b) are actually calling Dispose or are in a using statement. I've done quite a bit of work on LUCENENET-468, as well, though it is going far slower than 470, because there's a lot more that needs to be done and a bit more carefully, if I don't want to break anyone's code when they move to 3.0. I'm not doing them in any particular order, I'm really just running VS2010 code analysis (Rule CA1024 only, actually) and changing the ones suggested and ones I happen across to use Properties. I've also spent some time trying to wrap public fields in public properties. However, this one in particular has been posing some problems for me, and really brings me to the point of this email. Due to the way most class members are named (there's a lot of redundancy), I'm finding it difficult to move forward with some of these refactoring without breaking backwards compatibility or adding more things to change in regards to LUCENE-446 and CLS compliance. For classes that are specifically marked internal, this of course, hasn't been a problem, I just make the breaking change and fix it other places in the library. This is, of course, a problem with class that are public, including classes that *should not* be marked public but are anyway. It's a little off topic, but we stray far sometimes from the access modifiers defined on the java classes. I've found that nearly all cases were because they were needed for the NUnit tests. That problem no longer exists in 3.0.3, as the Test library can now access those types in the core assembly. I personally feel that whenever we find an difference in access modifiers, we change it to match java, however, if customers are using that, well, now they can't. That's issue number one that I wanted to discuss with the group. Going back to the difficulties in ".NET-ifying" the API, often times if I want to convert a Get[name]()/Set[name]() group or individual method to a property, the resulting property name will conflict with an already existing public field, another method with the exact same name, or the name of the enclosing type itself. The latter can't easily be solved, so I'm not fretting too much about it. The first two are easier to solve, but not without breaking backwards compatibility for some users. Now, the API between 2.x and 3.x differs greatly, so some customers *may* have to make changes anyway. However, that's not a good rule, since most, if not all, of the breaking changes made to Lucene.NET were first obsoleted for a period of time, and thus they were given plenty of warning to change their code. Unfortunately, with these changes, we haven't given them the same notice. So far, I've been trying my best to make sure that all changes that have been made, have been done in a way that won't break any compatibility. All of the classes that now implement Dispose() still have a Close() method that's now obsoleted (see the PS). For properties, I've been keeping the Get/Set methods, moving the code to the property, and marking them obsoleted. I figure that this is the workflow we want, but I'm finding it's not always possible, so I'd like to see what the group has to say about it. How strict will we be? Thanks, Christopher P.S. So in regards to classes implementing Dispose() and backwards compatibility. Yes, they still have a Close() method that is obsoleted. However, with some classes, for me to make the change, I had to add IDisposable to an abstract class or interface. In some cases, it was breaking. If Close() before was abstract, I made the new protected void Dispose(bool) method abstract, removed virtual from Close() and had it call Dispose(). This is a breaking change since and class that inherited from that class will now have multiple build errors, one for trying to override a non-virtual member (Close()) and another for not implementing the protected dispose method. So, perhaps that needs to be discussed as well.