Sunday, March 30, 2008

Sample of StackTrace usage.

       Sometimes we want to store in log file error (warning or trace) message and stack trace, from where the message is stored. To solve the problem it is suggested to use class StackTrace.

public class StackTraceSampleClass
{
const string LOG_FILE_NAME = "stackTraceSample.log";
public void Execute()
{
File.Delete(LOG_FILE_NAME);
F1(-10);
F2(-10);
}
void F1(int arg)
{
F(arg);
}
void F2(int arg)
{
F(arg);
}
double F(int arg)
{
if (arg < 0)
{
StackTrace stackTrace = new StackTrace(true);
string logContent = String.Format("unexpected value of arg: {0}, stack: {1}", arg, stackTrace);
File.AppendAllText(LOG_FILE_NAME, logContent);
return 0;
}
return Math.Sqrt(arg);
}
}
File stackTraceSample.log in Debug mode:


stackTraceInDebugMode 


File stackTraceSample.log in Release mode:


stackTraceInReleaseMode 


Reference:



StackTrace Class



Sample of C# Trace.Fail() method.

Sample of C# Trace.Fail() method.

        Often we don't check input parameters, because we have a contract and expect valid parameters values. But sometimes, we want to control critical parameters and somehow inform about invalid input parameters.

In this case, we can use method Debug.Fail() or Trace.Fail().

static int CheckArgument(string argument)
{
    if (argument == null)
    {
        Trace.Fail("CheckArgument(): argument cannot be bull", "CheckArgument()");
        return 0;
    }
    return argument.Length;
}
Method CheckArgument doesn't expect to receive null, but if input parameter argument will be null, we call method Trace.Fail() with relevant message. By default, next message will be shown:

TraceFailErrorMessage

The message will be relevant in debug mode, but in production mode, we don't want to show message to user, but want to inform developer about the problem.

So, we want to change behavior of Fail.

First of all, let's implement new class MyTraceListener and override method Fail (actually 2 method Fails):

public class MyTraceListener : DefaultTraceListener
{
public override void Fail(string message)
{
SendNotification(message);
}
public override void Fail(string message, string detailMessage)
{
SendNotification(message + ", detailMessage: " + detailMessage);
}

void SendNotification(string message)
{
// here should be implemented sending email
StackTrace stackTrace = new StackTrace(1, true);
Trace.WriteLine("MyTraceListener notification: " + message + " in " + stackTrace);
}
}



Now, we should define the implemented MyTraceListener as single TraceListenerClass:


MyTraceListener listener = new MyTraceListener();
Trace.Listeners.Clear();
Trace.Listeners.Add(listener);




"Output Visual Studio" Window demonstrates possible notification's output:



TraceFailErrorOutput



Reference:



TraceListener.Fail Method



StackTrace Class



Sources can be found in "Code project C# tips samples" in project Debug, method sample_TraceFail().

Wednesday, March 26, 2008

How to convert simple types (basic operations) in c#.

To convert one simple type (for example int), to another simple type (for example float or string) it is suggested to use .NET class BitConverter.

C# code sample:

static void Main()
{
int intData = 0x01020304;
byte[] bytesData = BitConverter. GetBytes(intData);
float floatData = BitConverter.ToSingle(bytesData, 0);
string stringData = BitConverter.ToString(bytesData);
}


Result values (from VS Locals Window):


BitConverterResultsInLocals



Reference:



BitConverter Class

The simplest way to store object to .xml file in c#.

The simplest way to implement xml serialization in c#:

1. Add attribute [Serializable] for all classes.

2. All public fields will be serialized.

3. If you want to store field as xml attribute add attribute [XmlAttribute("")].

[Serializable]
public class SubData
{
[XmlAttribute("")]
public int subDataAsAttribute;
public int subData;
public int SubProperty { get { return subDataAsAttribute + subData; } }
}
[Serializable]
public class Data
{
public int publicIntData;
internal int internalIntData;
protected int protectedIntData;
private int privateIntData;
public SubData subData;
public Data()
{
}
public Data(int publicIntData)
{
this.publicIntData = publicIntData;
}
}



4. Create objects XmlSerializer and TextWriter and store needed object to xml file:



string xmlFilePath = "data.xml";
XmlSerializer serializer = new XmlSerializer(typeof(Data));
using (TextWriter writer = new StreamWriter(xmlFilePath))
{
serializer.Serialize(writer, data);
}


5. To read the stored object use XmlSerializer and TextReader:


Data actualData;
using (TextReader reader = new StreamReader(xmlFilePath))
{
actualData = (Data) serializer.Deserialize(reader);
}
6. See sample of relevant xml file:


xmlScreen 


Reference:


XmlSerializer Class

Tuesday, March 25, 2008

How to attach .NET sources in VS 2005

1. Download "Mass Downloader" from project site.

2. Unzip content of downloaded file NetMassDownloader.zip.

3. Run utility with next parameters:

NetMassDownloader.exe -vsver 8.0 -d C:\Windows\Microsoft.NET\Framework\v2.0.50727 -output D:\ReferenceSource_VS2005

where

folder D:\ReferenceSource_VS2005 is a target folder to download .NET sources.

Process of sources downloading had took 90 minutes on my computer with my Internet connection.

referenceSources_VS2005

4. It is necessary to add the folder to "Symbol file locations".

referenceSources_SetDebuggingSymbols

5. Uncheck "Require sources files to exactly match the original version" settings.

referenceSources_SetDebuggingRequireSources

6. Uncheck option "Enable Just My Code (Managed only):

referenceSources_SetDebuggingJustMyCode

7. In each solution, where we want to access to .NET sources, it is necessary to add next directory:

referenceSources_SetSolutionSettings

Now, when we debug next code:

static voidMain(){ int[] array = (int[]) Array.CreateInstance(typeof (int), 10);
//SampleFindAll();
//SampleFindIndex();
}
we can enter to .NET sources code (file Array.cs) by command "Step Into":

// Create instance will create an array
public unsafe static Array CreateInstance(Type elementType, int length)
{
if (elementType == null)
throw new ArgumentNullException("elementType");
RuntimeType t = elementType.UnderlyingSystemType as RuntimeType;
if (t == null)
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"elementType");
if (length < 0)
throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
return InternalCreate((void*)t.TypeHandle.Value,1,&length,null);
}

Reference:

View the .NET Sources Code in VS 2005

Sunday, March 23, 2008

Define how to display members of a class.

To control if and how a member of class will be displayed we can use attribute DebuggerBrowsable.

Default value Collapsed of attribute DebuggerBrowsable:

DebuggerBrowsable_Default

Value Never of attribute DebuggerBrowsable:

DebuggerBrowsable_Never

Value RootHidden of attribute DebuggerBrowsable:

DebuggerBrowsable_RootHidden 

Reference:

DebuggerBrowsableAttribute class

How to mark a method to avoid tracing in debugger.

When we want to avoid tracing a method in debugger, we can add attribute DebuggerStepThroughAttribute. If a method will be marked by the attribute, then debugger (Visual Studio) will not trace into the method (by command "Step Into") and breakpoint will not be enabled in body of the method.

Sample:

SampleDebuggerStepThroughAttribute

Method Method_not_Debugable() is marked by attribute DebuggerStepThroughAttribute and we cannot trace it by debugger's command "Step into" and set breakpoint inside the method.

Output:

OutputSampleDebuggerStepThroughAttribute

Reference:

DebuggerStepThroughAttribute Class

Source file of the sample

 

Friday, March 21, 2008

Sample of C# Debug.Assert() method.

Often we want to check something (input parameters of a method, external output, etc.) in debug mode (development and testing time) to control purposes, but we want to avoid additional overhead in release (production).

To solve the problem it is suggested to use method Debug.Assert.

For example, we want to control input parameter y of a method divide

static int divide(int x, int y)
{
Debug.Assert(y==0, "parameter y should not be zero");
return x/y;
}

Now, parameter will be checked and a message will be shown when value of y will be 0.





But in Release mode, the parameter y will not be checked and we avoid the additional overhead.

With help of reflector let's see compiled code in Debug and Release modes:

Debug mode





Release mode








Reference:

Assertions in Managed Code

Thursday, March 20, 2008

Pseudo variable $exception in VS2005

When a exception is caught and we want to check properties of the exception, we can use pseudo variable $exception (VS2005).

try
{
throw new Exception("test $Exception");
}
catch
{
Debug.WriteLine("exception");
}

Also variable $exception can be added to "Watch" window:

pseudoVariableDollarException

Tuesday, March 18, 2008

C# statement using and null.

Frequently calling of method Dispose (or finish of statement using) for a object means, that the object is not actual (because a resources are deleted in Dispose). If we check actuality of the object by checking for null, then we cannot use the checking after using.

For example, this code will not set null to the object customerDisposableClass

Trace.WriteLine("after definition ==> customerClass == null: " + (customerDisposableClass == null));
using (customerDisposableClass = new CustomerDisposableClass())
{
// statements
}
Trace.WriteLine("after Dispose() ==> customerClass == null: " + (customerDisposableClass == null));
Console output: 
consoleOutput1
Sure, we can set null by statement customerDisposableClass = null and add section try .. finally
(because if a exception will be raised inside statement using we will not set null).
I tried to find a suitable solution and can suggest to implement a next wrapper
public class CustomerClassWrapper: IDisposable
{
CustomerClass customerClass;
public CustomerClassWrapper(
CustomerClass customerClass,
CustomerDisposableClass customerDisposableClass)
{
this.customerClass = customerClass;
this.customerClass.customerDisposableClass = customerDisposableClass;
}
#region IDisposable
public void Dispose()
{
customerClass.customerDisposableClass.Dispose();
customerClass.customerDisposableClass = null;
}
#endregion
}

and use the wrapper by next way:
Trace.WriteLine("after definition ==> customerClass == null: " + (customerDisposableClass == null));
using (new CustomerClassWrapper(this, new CustomerDisposableClass()))
{
// statements
}
Trace.WriteLine("after Dispose() ==> customerClass == null: " + (customerDisposableClass == null));
Console output:
consoleOutput2 
Yes, I understand the solution helps per class (not for all all classes).
If somebody can suggest better solution, please, post in comments.
Reference

C# Language Specification. The using statement.

Statement "using" in blog csharp-tips

sources (from Code project "C# tips samples")

Monday, March 17, 2008

Sample of C# application tracing (class Trace).

To implement tracing in C# application it is suggested to use class Trace.

Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
TraceSwitch traceSwitch = new TraceSwitch("TraceLevelSwitch", "trace switch");

Trace.WriteLine("sample_Trace.Start");
for (int i = 0; i < 5; i++)
{
Trace.Indent();
Trace.WriteLineIf(traceSwitch.TraceInfo, "index: " + i + " indentLevel: " + Trace.IndentLevel);
Trace.Unindent();
}
Trace.WriteLine("sample_Trace.Finish");
VS Output window:

VS_output

Console screen:

console_output

Trace.Listeners allows to add additional trace target (in the sample, Console).

TraceSwitch helps to implement different levels of tracing.

When value of "TraceLevelSwitch" will be set "4" (see App.config file), then output will be next:

App.config file:

appConfigContent

VS Output window:

VS_output_traceLevel_4

Console screen:

console_output_traceLevel_4

Notes:

In Visual Studio 2005 projects, by default, the "DEBUG" conditional compilation symbol is defined for debug builds, and the "TRACE" symbol is defined for both debug and release builds. For information on how to disable this behavior, see the Visual Studio 2005 documentation.

Reference:

Trace Class

source of sample

App.config file

How to convert a byte array to string and back

To convert byte array to string it is suggested to use class Encoding

class ConvertUtils:

public class ConvertUtils
{
public static string ConvertBytesToString(byte[] data)
{
return Encoding.GetEncoding(1251).GetString(data);
}
public static byte[] ConvertStringToBytes(string data)
{
return Encoding.GetEncoding(1251).GetBytes(data);
}
}

Example:

It is a very important to test converting with help of 0xFD..0xFF (253 - 255) values, because a some code pages cannot convert these values correct.

byte[] inputData = new byte[] {0, 1, 2, 3, 0xFD, 0xFE, 0xFF};
string convertedData = ConvertUtils.ConvertBytesToString(inputData);
byte[] outputData = ConvertUtils.ConvertStringToBytes(convertedData);

Results:

watchWindow

Reference

Encoding Class

Saturday, March 15, 2008

Debug.WriteLine

When it is necessary to write a debug information for debug purposes only, then it is suggested to use method Debug.WriteLine, which writes information to Visual Studio (VS) "Output" window or to any debugger (for example, WinDebug)  "Output" window. It is a very important, that in Release mode, Debug.WriteLine is ignored.

using System.Diagnostics;

namespace DebugSamples
{
    class Program
   
{
        static void Main(string[] args)
        {
            Debug.WriteLine("Debug.Sample.Main(); start", "Trace");
            // ...
           
Debug.WriteLine("Debug.Sample.Main(); finish", "Trace");
        }
    }
}

Visual Studio "Output" window

VS_output

WinDebug "Output" window

WinDbg_output

Reference:

Debug..::.WriteLine Method

How to trace and debug in Visual C#

Friday, March 14, 2008

Array.FindAll

To extract from array a sub array by a condition can be used next way:

List<int> subList = new List<int>();
for (int i = 0; i < data.Length; i++)
{
if (data[i] >= minValue && data[i] <= maxValue)
subList.Add(data[i]);
}
return subList.ToArray();

Bug csharp it is suggested to use method Array.FindAll by next way:

return Array.FindAll(data, delegate(int value)
{
return value >= minValue && value <= maxValue;
});

Reference:

Array..::.FindAll<(Of <(T>)>) Generic Method

Thursday, March 13, 2008

Array.FindIndex

To find index of a element in array often we use statement for by next way:

static int SearchIndexOfItemInArray_via_for(int[] data, int foundItemValue)
{
int itemIndex = -1;
for (int i = 0; i < data.Length; i++)
{
if (foundItemValue == data[i])
{
itemIndex = i;
break;
}
}
return itemIndex;
}
C# (2.0) suggests another way to search index of element with help of method Array.FindIndex and delegate:

static int SearchIndexOfItemInArray_via_FindIndex(int[] data, int foundItemValue)
{
return Array.FindIndex(data, delegate(int item)
{
return item == foundItemValue;
});
}
Additional links:

Array..::.FindIndex<(Of <(T>)>) Generic Method (array<T>[]()[], Predicate<(Of <(T>)>))

Predicate<(Of <(T>)>) Generic Delegate

Wednesday, March 12, 2008

Operator set in method's parameters.

Usually before method's calling we set all method's parameters by next way:

int value;

value = 4;
Console.WriteLine(String.Format("sqrt({0}) = {1}", value, Math.Sqrt(value)));
value = 9;
Console.WriteLine(String.Format("sqrt({0}) = {1}", value, Math.Sqrt(value)));

But C# allows set of method's parameters during method's calling by suggested way:

Console.WriteLine(String.Format("sqrt({0}) = {1}", value = 25, Math.Sqrt(value)));
Console.WriteLine(String.Format("sqrt({0}) = {1}", value = 16, Math.Sqrt(value)));

Console output:

consoleOutputSet

All sources can be download from google code project csharp-tips "google code" project

Tuesday, March 11, 2008

How to rethrow exception in C#.

When a exception is caught and it is necessary to process the exception and rethrow it, then statement throw can be used.

If it is necessary to throw new exception:

try
{
throw exp;
}
catch (Exception e)
{
Debug.Write(e.Message); // Exception processig

throw new Exception("DoException", e);
}
If it is necessary to throw caught exception next:
try
{
throw exp;
}
catch (Exception e)
{
Debug.Write(e.Message); // Exception processig

throw;
}

First code will generate exception System.Exception and second code will generate exception exp (in our test sample Exception1).
Console output:
consoleOutput_RethrowException 

All sources can be download from google code project csharp-tips "google code" project

Additional Links:

throw (C# Reference)

Processing specific exception in C#

It is necessary to process a specific exception type and re-throw the exception next.

This code will process a specific exception Exception1, but section finally will be processed in any case:

            try
{
throw exp;
}
catch (Exception1)
{
Console.WriteLine("catched Exception1 ");
throw;
}
finally
{
Console.WriteLine("finally");
}
Correct code to process a specific exception should be next:
try
{
throw exp;
}
catch (Exception1)
{
Console.WriteLine("catched Exception1 ");
throw;
}
catch (Exception e)
{
Console.WriteLine("catched not Exception1");
}
See console output of these samples:
consoleOutput 


Monday, March 10, 2008

C# and Calendars

C# provides abstract class Calendar, which implements basic calendar operations, and different calendar implementations:

GregorianCalendar, HebrewCalendar, HijriCalendar, JapaneseCalendar, JulianCalendar, KoreanCalendar, TaiwanCalendar, and ThaiBuddhistCalendar.

Sample of calendars usage:

using System;
using System.Globalization;

namespace CalendarSamples
{
class Program
{
static void Main()
{
DateTime now = DateTime.Now;

HebrewCalendar hebrewCalendar = new HebrewCalendar();
String hebrewDate = String.Format("{0} {1} {2}",
hebrewCalendar.GetDayOfMonth(now),
hebrewCalendar.GetMonth(now),
hebrewCalendar.GetYear(now));

GregorianCalendar gregorianCalendar = new GregorianCalendar();
String gregorianDate = String.Format("{0} {1} {2}",
gregorianCalendar.GetDayOfMonth(now),
gregorianCalendar.GetMonth(now),
gregorianCalendar.GetYear(now));

JulianCalendar julianCalendar = new JulianCalendar();
String julianCDate = String.Format("{0} {1} {2}",
julianCalendar.GetDayOfMonth(now),
julianCalendar.GetMonth(now),
julianCalendar.GetYear(now));

Console.WriteLine("date: " + now);
Console.WriteLine("hebrew date: " + hebrewDate);
Console.WriteLine("gregorianCalendar date: " + gregorianDate);
Console.WriteLine("julianCalendar date: " + julianCDate);
}
}
}





Additional Links:

Sunday, March 9, 2008

C# basic compression and decompression services.

To compress and decompress a data it is suggested to use class DefalteStream or GZipStream

using System.IO;
using System.IO.Compression;

namespace zip_usage
{
class Program
{
static Stream CreateCompressStream(Stream inputStream, CompressionMode compressionMode)
{
//return new GZipStream(inputStream, compressionMode, true);
return new DeflateStream(inputStream, compressionMode, true);
}
static void Main()
{
string inputFileName = @"..\..\Data\inputData.bin";
string compressedFileName = @"..\..\Data\compressedData.zip";
string resultFileName = @"..\..\Data\outputData.bin";

byte[] inputBuffer = File.ReadAllBytes(inputFileName);
using (FileStream outputStream = File.OpenWrite(compressedFileName))
{
using (Stream compress = CreateCompressStream(outputStream, CompressionMode.Compress))
{
compress.Write(inputBuffer, 0, inputBuffer.Length);
}
}

byte[] resultBuffer = new byte[inputBuffer.Length];
using (FileStream compressedStream = File.OpenRead(compressedFileName))
{
using (Stream decompress = CreateCompressStream(compressedStream, CompressionMode.Decompress))
{
decompress.Read(resultBuffer, 0, resultBuffer.Length);
}
}

File.WriteAllBytes(resultFileName, resultBuffer);
}
}
}



Additional Links: System.IO.Compression Namespace

Thursday, March 6, 2008

How to send email and check without real SMTP server.

To send email via SMTP server see next sample code

using System.Net.Mail;
using System.Text;
 
namespace email_functions
{
    class Program
    {
        static void Main(string[] args)
        {
            string host = "test.com";
            SmtpClient smtpClient;
            MailAddress sender;
            MailAddress recipient;
 
            smtpClient = new SmtpClient(host);
            smtpClient.Timeout = 3000;
 
            sender = new MailAddress("sender@test.com", "Sender");
            recipient = new MailAddress("recipient@test.com", "Recipient");
 
            MailMessage message = new MailMessage(sender, recipient);
            message.SubjectEncoding = Encoding.UTF8;
            message.Subject = "test Smtp";
 
            smtpClient.Send(message);
        }
    }
}

But if real SMTP server (in sample, "test.com") is not accessible, then next error will be shown:






To test sending email without real SMTP server it is suggested to add section to .config file:


Notes:

  • Folder "c:\testEmailsFolder" should be created before email sending.
  • After .config file changes a program should be restarted.

Now, when the sample will finished, then text file .eml will be creared in folder "c:\testEmailsFolder". The file can be opened in Windows Live Mail.

X-Sender: Sender 
X-Receiver: Recipient
MIME-Version: 1.0
From: Sender
To: Recipient
Date: 6 Mar 2008 13:16:24 +0200
Subject: =?utf-8?B?dGVzdCBTbXRw?=

Additional Links:

SmtpClient..::.DeliveryMethod Property

Wednesday, March 5, 2008

Correct usage of IDisposable.

Original source code (write a text to text file):
--------------------------------------------------------------------
StreamWriter writer = new StreamWriter(filePath);
for (int i = 0; i < result.Length; i++)
{
writer.WriteLine(result[i].name + ": " + result[i].value);
}
writer.Flush();
--------------------------------------------------------------------

Class StreamWriter implements interface IDisposable, then we should call method Dispose(), which closes all unmanaged resources (and executes another 'destructor' actions).

Picture (Device Independent Bitmap)

Original code should be rewritten in another ways (when we call Dispose(), we may not close Flush()) :

--------------------------------------------------------------------

StreamWriter writer = new StreamWriter(filePath);
for (int i = 0; i < result.Length; i++)
{
writer.WriteLine(result[i].name + ": " + result[i].value);
}
writer.Flush();
writer.Dispose();

--------------------------------------------------------------------

or, more correctly,

--------------------------------------------------------------------

StreamWriter writer = new StreamWriter(filePath);
try
{
for (int i = 0; i < result.Length; i++)
{
writer.WriteLine(result[i].name + ": " + result[i].value);
}
}
finally
{
writer.Dispose();
}

--------------------------------------------------------------------

C# suggest statement "using" to call Dispose() method

--------------------------------------------------------------------

using (StreamWriter writer = new StreamWriter(filePath))
{
for (int i = 0; i < result.Length; i++)
{
writer.WriteLine(result[i].name + ": " + result[i].value);
}
}

--------------------------------------------------------------------

using Statement (C# Reference) http://msdn2.microsoft.com/en-us/library/yh598w02.aspx
As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement. The using statement calls the Dispose method on the object in the correct way, and (when you use it as shown earlier) it also causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and cannot be modified or reassigned.

Monday, March 3, 2008

Method File.AppendAllText

     To add any text to test file, can be used method

File.AppendAllText(String path, String contents)

   1: string fileName = Path.GetTempFileName();


   2: string fileContent = "sample of method File.WriteAllText";


   3: File.WriteAllText(fileName, fileContent);




Additional Links:



File..::.AppendAllText Method (String, String)



File..::.AppendAllText Method (String, String, Encoding)

Method Path.Combine()

To Combine 2 path strings (for example, file path and file name) it is suggested method

Path.Combine(string path1, string path2).

Samples:

Path1 Path2 Path.Combine()
"C:\\Temp" "file.txt" "C:\\Temp\\file.txt"
"C:\\Temp" "C:\\Temp\\file.txt" "C:\\Temp\\file.txt"

Additional Links:

Path..::.Combine Method

Sunday, March 2, 2008

C# function String.IsNullOrEmpty()

If it is necessary to check string variable on null and "" (empty), then

function String.IsNullOrEmpty can be used:


c0de with operator 'if'

string getName(string name)

{
if (name == null || name == "")
return "default";
else
return name;
}


code with function Sgtring.IsNullOrEmpty()


string getName_with_function_IsNullOrEmpty(string name)
{
if (String.IsNullOrEmpty(name))
return "default";
else
return name;
}


Sample can be download:

http://code.google.com/p/csharp-tips/source/browse/trunk/string_functions/Program.cs

Additional Links:
String..::.IsNullOrEmpty Method