20 September 2007

Compressing files

.Net framework supports two kinds of compressing types: GZipStream and DeflateStream. The different between these types is that the first one allows for headers that include extra information that might be helpful to decompress a file with the widely used gzip tool. Both of them use the same algorithm and both are free of patent protection so you can use them in commercial projects.
Below I will write the method to compress and decompress any data or file with using GZipStream. If you want to use the DeflateStream simply change the type in this code from GZipStream on DeflateStream.

public static void Compressing(string source, string destination)

{

FileStream src = null;

FileStream dest = null;

try

{

src = File.OpenRead(source);

dest = File.Create(destination);

GZipStream compress = new GZipStream(dest, CompressionMode.Compress);

int b = src.ReadByte();

while (b != -1)

{

compress.WriteByte((byte)b);

b = src.ReadByte();

}

}

finally

{

if (src != null)

src.Close();

if (dest != null)

dest.Close();

}

}

public static void Decompress(string source, string destination)

{

FileStream src = null;

FileStream dest = null;

try

{

src = File.OpenRead(source);

dest = File.Create(destination);

GZipStream compress = new GZipStream(src, CompressionMode.Decompress);

int b = compress.ReadByte();

while (b != -1)

{

dest.WriteByte((byte)b);

b = compress.ReadByte();

}

}

finally

{

if (src != null)

src.Close();

if (dest != null)

dest.Close();

}

}

Labels:

18 September 2007

Widening vs Narrowing

In .NET environment we have two ways for converting from one value type to our custom type. The first way is widening (implicit), by this conversions we don't lose precision i.e.

Int16 i16 = 0;

Int32 i32 = 100;

i32 = i16;


The second one is Narrowing (explicit) where is possible to lose some precision i.e.

Int16 i16 = 0;

Int32 i32 = 100;

i16 = (Int16)i32;



Below I will show you how to extend our type of explicit and implicit conversion.

class TestClass

{

public int ValueA;

public TestClass()

{

this.ValueA = 0;

}

public static explicit operator int(TestClass arg)

{

return arg.ValueA;

}

public static implicit operator TestClass(int arg)

{

TestClass t = new TestClass();

t.ValueA = arg;

return t;

}

}

Labels:

Boxing and unboxing

As everybody should know boxing and unboxing are tasks which take some valuable time. Of course we will not feel any different in invoking this function just couple times, but in case of hundred thousands invokes that can be noticeable. To build a faster programs I will describe couple good practices which you should be remember and use in this surface.
  • use overload methods for different arguments instead of using one which can accept only object argument

public virtual void DoIt(int i) { }

public virtual void DoIt(double d) { }

public virtual void DoIt(string s) { }

  • use generic types instead of using objects arguments

public List<int> collection = new List<int>();

  • overload methods ToString, Equals and ToHash in structurs to avoid boxing

struct TestStruct

{

public int ValueA;

public int ValueB;

public TestClass()

{

ValueA = 0;

ValueB = 0;

}

public override string ToString()

{

return String.Format("{0} {1}", this.ValueA, this.ValueB);

}

public override bool Equals(object obj)

{

if (obj == null)

return false;

if (this.GetType() != obj.GetType())

return false;

TestStruct comperable = (TestStruct)obj;

if (!this.ValueA.Equals(comperable.ValueA) || !this.ValueB.Equals(comperable.ValueB))

return false;

return true;

}

public override int GetHashCode()

{

return this.ValueA ^ this.ValueB;

}

}

17 September 2007

Dynamically calling generic methods

Generic methods are very useful in building OO applications. Last time while factoring my old code I found some problems to invoke a method with generic type. So when I found this solution I decided to share with you. This sample is very easy to implement in many ways but my point is to show you how to use method with dynamical type.

In example I have a class Display.

public class Display

{

public string display(T value)

{

return string.Format("value: {0} type: {1}", value, typeof(T).Name);

}

}


Now I would like to invoke the "Display" method with variable type i.e. int, string, double and so on. The easiest way is replacing i.e. T with int.

[TestFixture]

public class DisplayTest

{

[Test]

public void Display_display_Test()

{

Display d = new Display();

string result = d.display<int>(100);

Assert.AreEqual("value: 100 type: Int32", result);

}

}


I know that is now correct answer because I have to know which type is going to be used. The right answer it is an example below.

[TestFixture]

public class DisplayTest

{

[Test]

public void Display_display_Test()

{

Display d = new Display();

int i = 100;

MethodInfo mi = typeof(Display).GetMethod("display");

MethodInfo miGeneric = mi.MakeGenericMethod(i.GetType());

string result = (string)miGeneric.Invoke(d, new object[] { i });

Assert.AreEqual("value: 100 type: Int32", result);

}

}