08 November 2012 CI Team

 

Because of the object orientation developers are used to describe their working information’s in objects. For example:

public List<Product> GetProducts()

But what about basic characteristics? For the date we have the DateTime Object in the Framework but what about all the other units: meter, Gigabyte and so on? The easiest answer: Usually we have whole numbers so we are going to use an integer.

That’s what an interface could look like:

public void SetMailboxSize(int mailboxSize)

Unfortunately this leaves the question what am I asked to enter? That’s what your colleague might answer:

public void SetMailboxSize(int sizeInKilobyte)

Okay, now we know what to enter into it. For me this worked well until we found out that while I calculated in Kibibit (of 2) he calculated in Kilobit (of 10). By mischance you won’t find out about this mistake until you are working with huge amounts of information’s because the difference for 1 Gigabyte is only 24 Megabyte.

Another problem is that you might hand the method a wrong unit. For example the developer passes a 1 because the user chooses 1 gigabyte on the surface. The problem is that an integer has no expressiveness for the unit and can’t be validated therefore. Everything that wants to go wrong goes wrong at some point…

Because of this it is useful to create a class for every unit you might need.

public void SetMailboxSize(DataSize mailboxSize)

Beside the fact that you can’t enter a wrong unit another advantage is that you have all the code for the conversion of the units at one point.

Here is an example for what such a DataSize class could look like:

 /// <summary>
    /// Stores information about the size of data. The base unit is Byte, multiples are expressed in powers of 2.
    /// </summary>
    class DataSize
    {
        public enum Unit
        {
            Kilo = 1,
            Mega = 2,
            Giga = 3,
            Terra = 4,
            Peta = 5,
            Yotta = 6
        }
        public DataSize()
        { }
        /// <summary>
        /// Create a new DataSize Object
        /// </summary>
        /// <param name="bytes">number of bytes</param>
        public DataSize(UInt64 bytes)
        {
            Bytes = bytes;
        }

        /// <summary>
        /// Size of the data in Bytes
        /// </summary>
        public UInt64 Bytes { get; set; }

        /// <summary>
        /// converts the current value into
        /// </summary>
        /// <param name="unit"></param>
        /// <returns></returns>
        public Decimal ConvertTo(Unit unit)
        {
            return Decimal.Divide(Bytes, (Decimal)Math.Pow(1024 ,(int)unit));
        }

        /// <summary>
        /// Loads an amount of bytes
        /// </summary>
        /// <param name="unit">unit to load</param>
        /// <param name="value">bytes to load</param>
        public void GetFrom(Unit unit, Decimal value )
        {
            Bytes = Decimal.ToUInt64(value * (Decimal)Math.Pow(1024, (int)unit));
        }
    }

The information will be saved in a basic unit, in this example Byte, and converted into every possible other unit. It’s important that every real unit has an own data type that makes sure what it is about.