Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Sunday, April 8, 2012

Typed vs. Untyped Datasets

In last few posts we discussed how you can use data adapter, datatables and datasets to fetch data from and save it to SQL Server. In those examples, we created untyped datasets. Untyped dataset is simply an in memory declaration of a dataset. It is a collection of datatables, which themselves are in memory declaration of datatables which are similar to database tables.

While it is possible to create constraints such as column type, relationship between columns, whether a column is nullable or not in a datatable declared in memory, but you have to write extra code for it. Contrast that with a typed dataset which inherits from dataset class and has an XML schema. This allows for you to define constraints and relationships on the design surface. Additionally, you can also drag tables from the database on the design surface and relationships/constraints of your database will automatically follow.

In this example, we will create a dataset using AdventureWorks database and then dragging the tables on the design surface. I am using VS 2010 for this project.

1. Create a sample test project.
2. From the top menu select Data > Add New Data Source and connect to the database you would like to use.
3. Select database and click on Next
4. Create a New Connection or select an existing connection. Here we will create a new connection
5. Define parameters and select your database.
6. Select one or more tables/views/stored procedures/function you would like to include in this dataset. Here we will select all tables.
7. Click on Finish and it will create an xsd file with all the selected tables.

8. If you open the file, you will see all tables that are part of this xsd


Alternatively, you can also create an xsd file manually and drag the tables that you want on the design surface. Click on Add new file and then select an xsd file. Then drag the tables to the design surface. As you drag the tables, note the data type and relationship between the tables.


In addition to dragging the tables on the design surface, you can also add table(s) by right clicking on the design surface and then clicking on Add > New Table or create a new relationship constraint.


Using Typed Dataset

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace TypedDataSets
{
    class Program
    {
        static void Main(string[] args)
        {
            Customers customer1 = new Customers();
            //populate the dataset
            // Step 2: Specify a command (request)
            string connectionstring = System.Configuration.ConfigurationManager.
            ConnectionStrings["TypedDataSets.Properties.Settings.
            AdventureWorksConnectionString"].ToString();
            SqlConnection myConnection = new SqlConnection(connectionstring);
            myConnection.Open(); 
            SqlCommand myCommand = myConnection.CreateCommand();

            myCommand.CommandType = CommandType.Text;
            myCommand.CommandText = "SELECT TOP 10 CustomerID,TerritoryID,AccountNumber, " + 
                "CustomerType,rowguid,ModifiedDate FROM Sales.Customer";

            // now use data sets instead of data read
            SqlDataAdapter da = new SqlDataAdapter();
            da.SelectCommand = myCommand;
            da.Fill(customer1.Customer);

            Console.WriteLine("Customer ID: " + customer1.Customer[0].CustomerID);
            Console.Read();
        }
    }
}


Typed datasets allow for strong typing and allows for cleaner code, in the sense you don't have to convert data from one type to another or check for the data type before using it.

Thank you.

Thursday, March 1, 2012

C# Delegates

The concept of delegates is somewhat confusing and developers often wonder why we need them and where would we use delegates? We will discuss delegates with an example and hopefully clarify potential uses for them.

Consider a list object of a specific type. You can encapsulate one or more objects of the same type in this list and pass the list to other methods to read and do something with those objects. Delegates are similar in nature except that they encapsulate references to the methods of an object.

A delegate can encapsulate any method as long as method signatures are same as those of delegates. Use can then pass around those delegates or use them just as you would use the method encapsulated in those delegates.

Let's consider an example.

In this example, we will create a class which will take the hourly pay, hours worked, tax rate and return weekly pay as well as tax.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApp1
{
    class CalculateWeeklyPay
    {
        private double _hourlypay;
        private double _hours;
        private double _overtimerate;
        private double _taxrate;

   public CalculateWeeklyPay(double hourlypay, double hours, 
                             double overtime, double taxrate)
        {
            _hourlypay = hourlypay;
            _hours = hours;
            _overtimerate = overtime;
            _taxrate = taxrate;
        }
        public double calculateTax()
        {
            double grosspay = calculateGrossPay();
            double tax = grosspay * ((double)_taxrate / 100);
            return tax;
        }
  public double calculatePay(double hourlypay, double hours, 
                             double overtime, double taxrate)
        {
            _hourlypay = hourlypay;
            _hours = hours;
            _overtimerate = overtime;
            _taxrate = taxrate; 
            return calculatepay();
        }
        public double calculatePay()
        {
            return calculatepay();
         }
        private double calculatepay()
        {
            double grosspay = calculateGrossPay();
            double netpay = grosspay-(grosspay * ((double)_taxrate / 100));
            return netpay;
        }
        private double calculateGrossPay()
        {
            double basepay;
            double overtimepay = 0;
            double grosspay;
            
            if (_hours > 40)
            {
                overtimepay = (_hours - 40) * (_hourlypay * _overtimerate);
                basepay = 40 * _hourlypay;
            }
            else
            {
                basepay = _hours * _hourlypay;
            }
            grosspay = basepay + overtimepay;
            return grosspay;
        }
     }
}

Now, lets create a console app, which will instantiate this object and then return the weekly pay and tax. We will create two delegates. One delegate will work with two methods (CalculatePay and CalculateTax) and another delegate will work with overloaded CalculatePay method.

Note, a delegate must have the same signature and same return type of the referenced method that it will encapsulate.

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        //declared two deletages, one for each method
        //(since they have different signatures, you can't use same delegate)
        //also note return type for the delegate 
        //must be same as the return type of the signature.
        public delegate double delegate1();
        public delegate double delegate2(double hourlypay, double hours, 
                                         double overtime, double taxrate);
      
           
        static void Main(string[] args)
        {
            double hourlyPay = 7.50;
            double hours = 45;
            double overtimeRate = 1.5;
            double taxRate = 5;
          CalculateWeeklyPay calculatepay = new CalculateWeeklyPay(hourlyPay, 
                                                 hours, overtimeRate, taxRate);
            //you must instantiate a delegate
            delegate1 firstDelegate = new delegate1(calculatepay.calculatePay);
            Console.WriteLine("First Delegate {0} ", firstDelegate());
            Console.WriteLine(Environment.NewLine);
            //you can use same delegate for another method as long as 
            //its signatures and return type are same
            delegate1 anotherDelegate = new delegate1(calculatepay.calculateTax);
            Console.WriteLine("First Delegate Different Use {0} ", 
                              anotherDelegate());
            Console.WriteLine(Environment.NewLine);
            //let's use second delegate
            delegate2 secondDelegate = new delegate2(calculatepay.calculatePay);
            //you must pass the parameters that this delegate is expecting, 
            //otherwise a runtime error will occur
            Console.WriteLine("Second Delegate{0} ", 
                       secondDelegate(hourlyPay, hours, overtimeRate, taxRate));
            Console.WriteLine(Environment.NewLine);
            Console.Read();
        }
    }
}


One of the main use of delegates is in events. Suppose you want an object to notify another object when something happens. For example, a stock market object should fire an event when stock price changes for a stock you are watching. Another object (listener) can capture this event and do something with it instead of constantly polling the stock market object to see if the price has changed. In C#, you need delegates to create events such as this.

We will discuss events in future posts.

Thank you.

Friday, February 24, 2012

Structures in .NET

As we discussed in previous post, enumerations and structures are two complex types that are value types. Structures allow you encapsulate certain data elements similar to a class, except that structures are value types while classes are reference types.

Structures are very similar to classes with few differences.
  • Unlike classes, structures cannot inherit from other structures or a class, although they can implement interfaces.
    • Since they cannot inherit from other structures, an structure cannot be a base structure, which means structure members cannot be declared as "Protected".
  • Similar to classes, structures can have constructors, properties, methods etc.
  • Unlike classes, you cannot declare a parameterless constructor in a structure, although you can declare overloaded constructors with parameters. Strucutres always have a default constructor.
  • Unlike classes, you can instantiate an structure without using "new" operator.
Structures are suitable when you want to implement lightweight objects such as a point or color or a rectangle etc. 

Let's see an example in action...

    using System;
    struct StructExample
    {
        private int _width;
        private int _height;
   
        public int Width
        {
            get { return _width;}
            set {_width = value;}
         }

       public int Height
      {
           get { return _height;}
           set {_height = value;}
      }
   }


Let's use this structure

    Using System;
    class TestStructure
    {
       static void Main()
       {
             StructExample example1 = new StructExample();
             example1.Width  =1;
             example2.Height = 3;
             Console.WriteLine(example1.Width + ' ' + example1.Height);
             Console.Read();
        }
    }

As I mentioned previously, you should only use structures for lightweight objects because they are value types and are stored on a stack. Also, since they are not reference type, you are directly dealing with the structure and not with a reference, like you would with a class.

Thank you.








Sunday, February 12, 2012

C# or VB.NET -- aah the choices!

All Programming Fundamentals! Although there are many other supported languages in .NET Framework, when it comes to .NET development though, most applications are developed in either C# or VB.NET. I know, I know there is F# and what not. But the focus of this post and most of my other blogs would be on these two languages.

Gone are the days when C# was significantly better than VB.NET in terms of features etc. so most of the differences that remain now are superficial as well as preferential.

Still, I wanted to put down some of my thoughts as well as some of the arguments I have heard from either side.

So, which one is better? Well it depends on two factors...

  • Your own Experience / Preference.
  • Market Conditions.
For some reason, perhaps due to old VB 6 hangovers, C# developers are more in demand than VB.NET developers and I have seen more jobs in C# than VB.NET. Now, it may not be true in all markets but at least it is true on my side of the pond.

Still, there are a few subtle differences between the two and I will summarize them below, at least for the water cooler conversation, if nothing else. Note, there are syntantical differences like any language and we are not discussing them here.

  1. I don't know about you but I find it easier to read VB.NET code than C# code, due to its "English" like syntax. One developer once told me - "I don't understand why do I need to put a ; (semicolon) at the end of each line in C#."

  2. Line Continuation - If you want to continue one line into next, in VB.NET you have to do something like & _ while in C# you don't need to do anything. Just don't type ; (that's the answer I gave to the developer who asked me above question BTW). Although, in VB 2010 there is an implicit line continuation and you don't have to use _ anymore, but frankly if you are using VB.NET, I rather see  _.

  3. Previous versions of C# didn't support optional parameters to a method while VB.NET always did. Although latest C# release now supports optional parameters.

  4. Keywords in VB.NET are more self explanatory than C # (this goes to my #1 comment above). For example, to allow a method to be overridden in a derived class, you add a keyword "Overridable" to the method in VB.NET in the base class. In C#, you use keyword "Virtual" instead - not so intuitive, is it?

  5. Similarly if you don't want your method to be overriden, you use keyword "NotOverridable" in VB.NET but there is no such thing as "NotVirtual" in C#. Instead it is "Sealed".

  6. "With.... End With" in VB.NET has no equivalent in C#.NET.

  7. I personally feel that VB.NET IDE in Visual Studio has better intellisense than C# IDE.

  8. C# on the other hand is less forgiving if you make a mistake. For example, unless you have Option Strict ON, you can get away with converting a value type to a reference type or a string to an int etc. without typecasting it, which may impact the performance of your application or worst may result in run-time errors. C# will not let you convert one variable type to another without typecasting.

  9. If you have Option Explicit OFF, you can consume variables without declaring them in VB.NET, no such luck in C#.

  10. VB.NET is not case sensitive but C# is. I find that extremely annoying in VB.NET because I feel it is a poor coding practice to declare variable in one case and use it in another.

  11. VB.NET has much easier event handling. You can simply declare an event and raise it without having to implement any delegates. In C#, you have to use delegates.

  12. I find it much easier to read comments in C#. You use // to start the comment while ' in VB.NET. I like C# comment feature so much that even in VB.NET I use '// .

  13. It is much easier to port your skills from C# to Java or PHP as their syntaxes are somewhat similar. On the other hand VB syntax allows you to venture into other tools with VB Scripting support. For Example, SSRS Reports (you can create custom code in SSRS RDLC with VB.NET).
This is not an exhaustive list but the most common ones that I remember. If you feel I missed any, let me know and I will be glad to add to the list.

Your comments are welcome!