2 clarified question
source | link

Edit for clarification

With "consistency" I mean: The consistent behaviour of the class always taking ownership (and closing the stream) vs "best practice" to only take ownership of a object if you created it or explicitly transfered the ownership.

As for an example where it is enoying:

Assume you have two given classes (from some 3rd party library) which accept a stream to do something with it, like creating and processing some data:

 public class DataProcessor
 {
     public Result ProcessData(Stream input)
     {
          using (var reader = new StreamReader(input))
          {
              ...
          }
     }
 }

 public class DataSource
 {
     public void GetData(Stream output)
     {
          using (var writer = new StreamWriter(output))
          {
               ....
          }
     }
 }

Now I want to use it like this:

 Result ProcessSomething(DataSource source)
 {
      var processor = new DataProcessor();
      ...
      var ms = new MemoryStream();
      source.GetData(ms);
      return processor.ProcessData(ms);
 }

This will fail with an exception Cannot access a closed stream in the data processor. It's a bit constructed but should illustrate the point. There are various ways to fix it but nevertheless I feel that I work around something I should not have to.

Edit for clarification

With "consistency" I mean: The consistent behaviour of the class always taking ownership (and closing the stream) vs "best practice" to only take ownership of a object if you created it or explicitly transfered the ownership.

As for an example where it is enoying:

Assume you have two given classes (from some 3rd party library) which accept a stream to do something with it, like creating and processing some data:

 public class DataProcessor
 {
     public Result ProcessData(Stream input)
     {
          using (var reader = new StreamReader(input))
          {
              ...
          }
     }
 }

 public class DataSource
 {
     public void GetData(Stream output)
     {
          using (var writer = new StreamWriter(output))
          {
               ....
          }
     }
 }

Now I want to use it like this:

 Result ProcessSomething(DataSource source)
 {
      var processor = new DataProcessor();
      ...
      var ms = new MemoryStream();
      source.GetData(ms);
      return processor.ProcessData(ms);
 }

This will fail with an exception Cannot access a closed stream in the data processor. It's a bit constructed but should illustrate the point. There are various ways to fix it but nevertheless I feel that I work around something I should not have to.

1
source | link

Should consistency be favoured over programming convention?

When designing a class should consistency in behaviour be favoured over common programming practice? To give a specific example:

A common convention is this: If a class owns an object (e.g. it created it) it is responsible of cleaning it up once it's done. A specific example would be in .NET that if your class owns an IDisposable object it should dispose it at the end of its life. And if you don't own it then don't touch it.

Now if we look at the StreamWriter class in .NET then we can find in the documentation that it closes the underlying stream when it is being closed/disposed. This is necessary in cases where the StreamWriter is instantiated by passing in a file name as writer creates the underlying file stream and therefore needs to close it. However one can also pass in an external stream which the writer also closes.

This has annoyed me heaps of times (yes I know you can make a non-closing wrapper but that's not the point) but apparently Microsoft has made the decision that it's more consistent to always close the stream no matter where it came from.

When I come accross such a pattern in one of my classes I usually create a ownsFooBar flag which gets set to false in cases where FooBar is injected via the constructor and to true otherwise. This way the responsibility of cleaning it up is passed to the caller when he passes the instance explicitly.

Now I'm wondering if maybe consistency should be in favour over best practice (or maybe my best practice is not that good)? Any arguments for/against it?