1. Static vs. instance
I think there are very clear guidelines about what is good OO design and what isn't. The
problem is that the blogosphere makes it hard to separate the good from the bad and ugly. You can find some kind of reference supporting even the worst practice you can think of.
And the worst practice I can think of is Global State, including the statics you mentioned and everyone's favorite Singleton. Some excerpts from Misko Hevery's classic article on the subject.
To really understand the dependencies, developers must read every line of code. It causes Spooky Action at a Distance: when running test suites, global state mutated in one test can cause a subsequent or parallel test to fail unexpectedly. Break the static dependency using manual or Guice dependency injection.
Spooky Action at a Distance is when we run one thing that we believe is isolated (since we did not pass any references in) but unexpected interactions and state changes happen in distant locations of the system which we did not tell the object about. This can only happen via global state.
You may not have thought of it this way before, but whenever you use static state, you’re creating secret communication channels and not making them clear in the API. Spooky Action at a Distance forces developers to read every line of code to understand the potential interactions, lowers developer productivity, and confuses new team members.
What this boils down to is that you should not supply static references to anything that has some sort of stored state. The only place I use statics is for enumerated constants, and I have misgivings about even that.
2. Methods with input parameters and return values vs. methods with none
The thing you need to realize is that methods that have no input parameters and no output parameters are pretty much guaranteed to be operating on some sort of internally stored state (otherwise, what are they doing?). There are entire languages that are built on the idea of avoiding stored state.
Any time you have stored state, you have the possibility for side-effects, so make sure that you always use it mindfully. This implies that you should prefer functions with defined inputs and/or outputs.
And, in fact, functions that have defined inputs and outputs are much easier to test--you don't have to run a function here and go look over there to see what happened, and you don't have to set a property somewhere else before you run the function under test.
You can also safely use this type of function as statics. However, I wouldn't, because if I then later wanted to use a slightly different implementation of that function somewhere, rather than providing a different instance with the new implementation, I'm stuck with no way to replace the functionality.
3. Overlapping vs. Distinct
I don't understand the question. What would the advantage be in 2 overlapping methods?
4. Private vs. Public
Don't expose anything you don't need to expose. However, I'm not a big fan of private, either. I'm not a C# developer, but an ActionScript developer. I've spent a lot of time in Adobe's Flex Framework code, which was written circa 2007. And they made some really bad choices of what to make private, which makes it kind of a nightmare trying to extend their Classes.
So unless you think you're a better architect than the Adobe developers circa 2007 (from your question, I'd say you have a few more years before you have a chance to make that claim), you probably want to just default to protected.
There are some problems with your code examples which mean that they're not well-architected, so it's not possible to pick A or B.
For one thing, you probably should separate your object creation from its use. So you usually wouldn't have your
new XMLReader() right next to where it is used.
Also, as @djna says, you should encapsulate the methods used in your XML Reader uses, so your API (instance example) might be simplified to:
_document Document = reader.read(info);
I don't know how C# works, but since I've worked with a number of web technologies, I'd be suspicious that you wouldn't always be able to return an XML document immediately (except maybe as a promise or future type object), but I can't give you advice on how to handle an Asynchronous load in C#.
Note that with this approach, you could create several implementations that can take a parameter that tells them where/what to read and return an XML object, and swap them based on your project needs. For example, you might be reading directly from a database, from a local store, or, as in your original example, from a URL. You can't do that if you use a static method.