Thursday, November 20, 2008

Difference between ref and out parameter in C#

Both the ref and out parameters are basically used to return values with the same variables that is passed as an argument to a method. But the difference is that the variable passed as an out parameter need not be initialized and is exclusively used for returning data to the caller whereas a variable passed as a ref parameter should be initialized and is used to pass as well as receive data from the method.
Eg:
For Passing by reference
static void Main(string[] args)
{
int i, j; //Should be initialized
i = 3;
j = 4;
PassByRef(ref i, ref j);
Console.WriteLine(i);
Console.WriteLine(j);
}
static void PassByRef(ref int var1, ref int var2)
{
var1 += 3;
var2 += 4;
}
Output is i=6, j=8
For Passing as Out
static void Main(string[] args)
{
int i, j; //Need not be initialized
PassByOut(out i, out j);
Console.WriteLine(i);
Console.WriteLine(j);
}
static void PassByOut(out int var1, out int var2)
{
var1 = 10;
var2 = 20;
}
Output is i=10, j=20

Monday, November 3, 2008

Using LINQ and Lambda expressions in Compact Framework 3.5

I tried adding a reference to System.Linq in my class but was not able to find the reference and was aghast at this. Then I found that to add a reference to System.Linq, first we should add a reference to the System.Core.dll using the Add Reference option. Then add
using System.Linq;
in the class file.
I had a requirement to filter out an array based on certain conditions , populate a struct and then bind the data to a list view.
Consider a simple example where I have an array with different Temperature Zones such as Hot, Cold and want to sum all the temperatures in hot and cold and display.
My Array[0].TempZone = "hot";
MyArray[0].Temperature = 30;
My Array[1].TempZone = "hot";
MyArray[1].Temperature = 40;
My Array[2].TempZone = "Cold";
MyArray[2].Temperature = 40;
My Array[3].TempZone = "Cold";
MyArray[3].Temperature = 50;
In this case, only 2 rows should be displayed in the list view with TempZone as Hot and Temperature as 30 + 40 = 70 and second row with TempZone as Cold and Temperature as 40 + 50 = 90.
I have a struct to fill in from the array
Struct MyStruct
{
String tempZone;
Int finalTemp;
}
To achieve this I used a simple LINQ query
var hotlist = from item in MyArray where item.TempZone == "hot" select item;
var coldlist = from item in MyArray where item.TempZone == "Cold" select item;
And then used Lambda expressions to obtain the sum as
lMystruct = new MyStruct[2];
lMystruct[0].TempZone = "hot";
lMystruct[0].Temperature = hotlist.Sum(hot => hot.Temperature);
lMystruct[1].TempZone = "Cold";
lMystruct[1].Temperature = coldlist.Sum(cold => cold.Temperature);
which is pretty simple and the struct can now be bound to a listview.
There may or may not be more than row with hot or cold and not necessarily in the same order in which case .Net code becomes pretty complex.

Thursday, October 23, 2008

Unit Testing in Visual Studio 2008

While generating unit tests in Visual Studio 2008, I came across this error when creating a unit test for a Strong named signed assembly
Error: Friend assembly reference 'AssemblyName' is invalid. Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations.
To fix this error, the steps are as:
1. Create a strong name key for the TestProject using the Visual Studio Command prompt
:sn –k “TestProject.snk”
2. Add the strong name key to the TestProject and in the properties of the TestProject, sign the assembly with the strong name key file
3. Extract the public key from the “TestProject.snk” and export it a new file as
sn –p TestProject.snk PublicKey.snk
4. Get the public key from the “PublicKey.snk file using
sn –tp PublicKey.snk
5. Add the public key in the AssemblyInfo.cs file as
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("TestProject1, PublicKey=0024000004800000940000000602000000240000525341310004000001000100274324f6df083237e787bcafcd35a1f9a746b018e7be3d3c47654aeed9d1efbf3ad0b47c00eaae26531b9b4965170680bc699fca7bb5f4eb87980fd12676d26aaaa84aa5f0c26f6187535dded0734a57fe5a88aeaee22997b021b7630676e53702d211fa47cb6c915b282e669c2f444c85e9e096fc0b222efa93e61751e20dba")]
This should resove the error.

Friday, October 17, 2008

Generating a proxy in WCF when generics is used

A weird problem we faced in our project was while generating a proxy class using Svcutil and WCF was returning a generics List using Visual Studio 2005 WCF extensions. An array was being generated for all the generic types.
By default svcutil command does not include System.Collection datatypes
By Default, the command is :
svcutil /l vb "http://localhost/SampleWCFService/SampleContract.svc?wsdl"
where SampleWCFService is a WCF service hosted on the IIS
If a service method returns or accepts a Generic List , then the svcutil command will be as follows :
svcutil /l vb /CollectionType:System.Collections.Generic.List`1 "http://localhost/SampleWCFService/SampleContract.svc?wsdl"
If the service accepts or returns more then one System.Collections datatypes,say, Hashtable and generic list then the command will be as follows :
svcutil /l vb /CollectionType:System.Collections.Hashtable /CollectionType:System.Collections.Generic.List`1 "http://localhost/SampleWCFService/SampleContract.svc?wsdl"

Monday, October 13, 2008

Basic differences between Windows and WPF application:


As a beginner to WPF having worked on Windows application, some of the basic differences that I came across between the two are:
1. The Windows class derives from System.Windows.Forms namespace whereas a WPF class derives from the System.Windows.Window namespace
2. The program.cs file was used to specify the startup class in a Windows app but in a WPF app, the Startup Uri in the App.xaml can be used to specify the startup class.
3. The name attribute for any control was mandatory in a Windows app, but is not mandatory for a WPF application. Eg: If I have 2 buttons in a WPF form without any name property, if I add a click event for the 2 buttons the events generated are
private void Button_Click(object sender, RoutedEventArgs e)
{
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
}
4. If you noticed in the previous example, the RoutedEventArgs is something new compared to the EventArgs in a Windows App. So, what is the difference between the two?
A Routed event can not only occur on the object that initially raises it but also on objects related to it i.e. the event can be passed on.
Some good links to get started with WPF are
http://aspalliance.com/articles/LearnWPF.aspx
http://windowsclient.net/