patterns-group / code-patterns

Code Patterns: lots of reusable goodies for your .NET project
tribesoftware.org/code-patterns/
BSD 2-Clause "Simplified" License
9 stars 9 forks source link

new type: Patterns.IO.FileSize #71

Open jbatte47 opened 10 years ago

jbatte47 commented 10 years ago

AC: the following code has been added to Patterns along with features supplying coverage of each helper method

/// <summary>
///     Provides quick access to Windows-compliant file size measurements.
/// </summary>
public static class FileSize
{
   private const long _kb = 1024;
   private const long _mb = _kb*_kb;
   private const long _gb = _mb*_kb;
   private const long _tb = _gb*_kb;
   private const long _pb = _tb*_kb;

   /// <summary>
   ///  Gets the specified number of kilobytes.
   /// </summary>
   /// <param name = "kilobytes">The kilobytes.</param>
   /// <returns></returns>
   public static long FromKilobytes(int kilobytes)
   {
      return _kb*kilobytes;
   }

   /// <summary>
   ///  Gets the specified number of megabytes.
   /// </summary>
   /// <param name = "megabytes">The megabytes.</param>
   /// <returns></returns>
   public static long FromMegabytes(int megabytes)
   {
      return _mb*megabytes;
   }

   /// <summary>
   ///  Gets the specified number of gigabytes.
   /// </summary>
   /// <param name = "gigabytes">The gigabytes.</param>
   /// <returns></returns>
   public static long FromGigabytes(int gigabytes)
   {
      return _gb*gigabytes;
   }

   /// <summary>
   ///  Gets the specified number of terabytes.
   /// </summary>
   /// <param name = "terabytes">The terabytes.</param>
   /// <returns></returns>
   public static long FromTerabytes(int terabytes)
   {
      return _tb*terabytes;
   }

   /// <summary>
   ///  Gets the specified number of petabytes.
   /// </summary>
   /// <param name = "petabytes">The petabytes.</param>
   /// <returns></returns>
   public static long FromPetabytes(int petabytes)
   {
      return _pb*petabytes;
   }
}
jbatte47 commented 10 years ago

Each of the constants listed above should be made available as public constant fields. Let the consumer know what they're getting with each value:

long kb = FileSize.OneKilobyte;
jbatte47 commented 10 years ago

And now that I read it, it looks ridiculous, unless the type itself is ridiculous, and I'm just now picking up on it. If we expose the base FileSize values as public constants, then how is FileSize.FromMegabytes(5) any easier than just going with FileSize.OneMegabyte * 5? It's exactly as complex as consuming the method, and the method can just not exist. I'm gonna need some of The Tribe to chime in on this one because I'm a little torn about which way to go. One of the ways to go that I'm considering is to just drop this altogether since it's seeming less and less helpful all the time.

blaw2422 commented 10 years ago

I agree with the last thought. 1024 x N right?

Brandon Law On Jan 9, 2014 6:10 PM, "John Batte" notifications@github.com wrote:

And now that I read it, it looks ridiculous, unless the type itself is ridiculous, and I'm just now picking up on it. If we expose the base FileSize values as public constants, then how is FileSize.FromMegabytes(5)any easier than just going with FileSize.OneMegabyte

  • 5? It's exactly as complex as consuming the method, and the method can just not exist. I'm gonna need some of The Tribe to chime in on this one because I'm a little torn about which way to go. One of the ways to go that I'm considering is to just drop this altogether since it's seeming less and less helpful all the time.

— Reply to this email directly or view it on GitHubhttps://github.com/TheTribe/code-patterns/issues/71#issuecomment-31991214 .

Wesam18 commented 10 years ago

I with dropping this altogether. The whole concept can be a part of metrics conversion class.

chrislwade commented 10 years ago

Why not a bunch of extension methods so you could just do 5.megabytes() or 1.5.gigabytes().?

jbatte47 commented 10 years ago

^^^ I feel like Wesam's answer is almost spot-on, but a metric conversion class that concerned itself with anything other than file sizes would break SRP by doing so. I really love Chris's idea. It feels SO Ruby. I wonder why that is ;)

jbatte47 commented 10 years ago

Chris: if we did that, we'd have to offer extensions for all the numeric types. That's:

chrislwade commented 10 years ago

I take it that none of those types inherit from Number or something similar? And realistically, how bad would it be to do so? Yes, it would be a ton of small methods but why is that a problem? It's not really about "conversion" of types as it is making things convenient for the programmer using the methods. 5.Megabytes() is much more natural coming from other languages when compared to 'FileSize.FromMegabytes(5)`.

jbatte47 commented 10 years ago

The common base type is ValueType, which is not descriptive enough and is not a valid extension target. It's not bad to do this though. I like your idea best so far. I just want to make sure we don't miss any of the numeric types. On Jan 9, 2014 7:04 PM, "Christopher Wade" notifications@github.com wrote:

I take it that none of those types inherit from Number or something similar? And realistically, how bad would it be to do so? Yes, it would be a ton of small methods but why is that a problem? It's not really about "conversion" of types as it is making things convenient for the programmer using the methods. 5.Megabytes() is much more natural coming from other languages when compared to 'FileSize.FromMegabytes(5)`.

— Reply to this email directly or view it on GitHubhttps://github.com/TheTribe/code-patterns/issues/71#issuecomment-31994242 .

jbatte47 commented 10 years ago

I'm taking this, and I'm gonna do both things: expose a FileSizes type with constants for one of each: KB, MB, GB, TB, PB. Also, a set of extensions returning long, double, or float values depending on the target type. E.g.:

3.5.Gigabytes().Should().BeGreaterThan(3500.Megabytes()); //which seems weird at first
blaw2422 commented 10 years ago

Stupid question. .. why do you need it? What were you doing that made you want this? Just playing Devil's advocate. ..

Brandon Law On Jan 9, 2014 9:08 PM, "John Batte" notifications@github.com wrote:

I'm taking this, and I'm gonna do both things: expose a FileSizes type with constants for one of each: KB, MB, GB, TB, PB. Also, a set of extensions returning long, double, or float values depending on the target type. E.g.:

3.5.Gigabytes().Should().BeGreaterThan(3500.Megabytes()); //which seems weird at first

— Reply to this email directly or view it on GitHubhttps://github.com/TheTribe/code-patterns/issues/71#issuecomment-31999289 .

jbatte47 commented 10 years ago

It's to fill a very small gap. It's similar to the gap that you'd feel if there were no TimeSpan.FromMinutes(5) to call. If you had to use new TimeSpan(0, 5, 0) every time, you'd want your convenience method back because it lets you express your wishes using the logical units you were already thinking in. This class's purpose was to allow the same experience to exist when assigning size limits or buffer lengths to things:

logOptions.Mode = LogModes.RollingFile;
logOptions.MaxFileSize = FileSize.FromMegabytes(5);

Only now, with the new syntax, it will look more like:

logOptions.MaxFileSize = 5.Megabytes();

Which I like a LOT better.