7/28/09

Object Initializers and Collection Initializers

New C# Language Feature: Automatic Properties

If you are a C# developer today, you are probably quite used to writing classes with basic properties like the code-snippet below:

public class Person {

private string _firstName;
private string
_lastName;
private int
_age;

public string
FirstName {

get {
return _firstName;
}
set {
_firstName
= value;
}
}

public string LastName {

get {
return _lastName;
}
set {
_lastName
= value;
}
}

public int Age {

get {
return _age;
}
set {
_age
= value;
}
}
}

Note about that we aren't actually adding any logic in the getters/setters of our properties - instead we just get/set the value directly to a field. This begs the question - then why not just use fields instead of properties? Well - there are a lot of downsides to exposing public fields. Two of the big problems are: 1) you can't easily databind against fields, and 2) if you expose public fields from your classes you can't later change them to properties (for example: to add validation logic to the setters) without recompiling any assemblies compiled against the old class.

The new C# compiler that ships in "Orcas" provides an elegant way to make your code more concise while still retaining the flexibility of properties using a new language feature called "automatic properties". Automatic properties allow you to avoid having to manually declare a private field and write the get/set logic -- instead the compiler can automate creating the private field and the default get/set operations for you.

For example, using automatic properties I can now re-write the code above to just be:

public class Person {

public string FirstName {
get; set;
}

public string LastName {
get; set;
}

public int Age {
get; set;
}
}

Or If I want to be really terse, I can collapse the whitespace even further like so:

public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}

When the C# "Orcas" compiler encounters an empty get/set property implementation like above, it will now automatically generate a private field for you within your class, and implement a public getter and setter property implementation to it. The benefit of this is that from a type-contract perspective, the class looks exactly like it did with our first (more verbose) implementation above. This means that -- unlike public fields -- I can in the future add validation logic within my property setter implementation without having to change any external component that references my class.

Bart De Smet has a great write-up on what happens under the covers when using automatic properties with the March CTP release of "Orcas". You can read his excellent blog post on it here.

New C# and VB Language Feature: Object Initializers

Types within the .NET Framework rely heavily on the use of properties. When instantiating and using new classes, it is very common to write code like below:

Person person = new Person();
person.FirstName = "Rambhopal";
person.LastName = "Reddy";
person.Age = 30;

Have you ever wanted to make this more concise (and maybe fit on one line)? With the C# and VB "Orcas" compilers you can now take advantage of a great "syntactic sugar" language feature called "object Initializers" that allows you to-do this and re-write the above code like so:

Person person = new Person { FirstName="Rambhopal", LastName="Reddy", Age=30 };

The compiler will then automatically generate the appropriate property setter code that preserves the same semantic meaning as the previous (more verbose) code sample above.

In addition to setting simple property values when initializing a type, the object initializer feature allows us to optionally set more complex nested property types. For example, assume each Person type we defined above also has a property called "Address" of type "Address". We could then write the below code to create a new "Person" object and set its properties like so:

Person person = new Person {
FirstName
= "Rambhopal",
LastName
= "Reddy"
Age = 30,
Address
= new Address {
Street
= "India",
City
= "Hyderabad",
State
= "AP",
Zip
= 500045
}
}
;

Bart De Smet again has a great write-up on what happens under the covers when using object initializers with the March CTP release of "Orcas". You can read his excellent post on it here.

New C# and VB Language Feature: Collection Initializers

Object Initializers are great, and make it much easier to concisely add objects to collections. For example, if I wanted to add three people to a generics-based List collection of type "Person", I could write the below code:

List people = new List();

people.Add( new Person { FirstName = "Rambhopal", LastName = "Reddy", Age = 30 } );
people.Add( new Person { FirstName = "Bill", LastName = "Gates", Age = 50 } );
people.Add( new Person { FirstName = "Susanne", LastName = "Guthrie", Age = 32 } );

Using the new Object Initializer feature alone saved 12 extra lines of code with this sample versus what I'd need to type with the C# 2.0 compiler.

The C# and VB "Orcas" compilers allow us to go even further, though, and also now support "collection initializers" that allow us to avoid having multiple Add statements, and save even further keystrokes:

List people = new List {
new Person { FirstName = "Rambhopal", LastName = "Reddy", Age = 30 },
new Person { FirstName = "Bill", LastName = "Gates", Age = 50 },
new Person { FirstName = "Susanne", LastName = "Guthrie", Age = 32 }
}
;

When the compiler encounters the above syntax, it will automatically generate the collection insert code like the previous sample for us.

Summary:

As developers we now have a much more concise way to define objects, initialize them, and add them to collections. At runtime, the semantics will be exactly the same as with today's longer syntax (so you don't need to worry about behavior changes). But now you don't need to type as much, and your code can be more crisp and concise.

In the near future I'll do additional blog posts that examine even more "Orcas" language improvements including Extension Methods, Lambdas, and Anonymous Types. I'll then do a deep dive into LINQ, and show how it takes advantage of all of these features to provide a really elegant way to query and interact with data.





Extension Methods

New to .NET 3.5 are a very powerful new paradigm called Extension Methods. Extension Methods, in a nutshell, are a way to extend the functionality of additional classes--adding new Methods to existing classes for the purpose of augmenting capability. The easiest way to demonstrate this is to show you a great example...

namespace ExtensionMethods
{
public static class StringExtensionMethods
{
public static bool IsNumeric(this string str)
{
try
{
int i = int.Parse(str);
return true;
}
catch
{
}
return false;
}
}
}

C#, as many of you know, lacks the built in VB.NET function, IsNumeric. (By the way, I can name a few things wrong with this particular extension method--so only use this example for the How-To of Extension Methods, not synthesizing IsNumeric) This extension Method extends the type string (the keyword "this" in the method signature is used to define what this method extends). With this newly written function, you can determine if a string is numeric by running code like this:

string s = "someValue";
bool bs = s.IsNumeric();
// bs is false;

string i = "7";
bool bi = i.IsNumeric();
// bi is true;

Now--as you may know, .NET strings do not intrinsically have a method IsNumeric() on them--this is our new Extension Method in action. In Visual Studio, you'll get intellisense if everything's set up right. Here's the rules you need to follow...

  1. All Extension Methods need to be defined in a static class
  2. All Extension Methods need to be defined as a static method.
  3. All Extension Methods need to take at least one parameter defined as follows:
    this (keyword) string (type) parameterName
    Where the type is whatever type that you wish to extend.
  4. The "this" parameter needs to be the first parameter. All other parameters are optional--and must follow "this".

Also I recommend the following points...

  1. Extension Methods adds complexity to your project and more importantly your IDE must parse these--don't go extension method crazy.
  2. Extension Methods should be extensions only. It's not advisable to define them in commonly used NameSpaces such as "System". That could be bad...
  3. If you're writing too many extension methods--maybe it's time to write a custom class that inherits from that data type, No?

A powerful tool, they are--extend the .NET framework they can. Enjoy them you must.

Also, technically, you can use 'em in .NET 2.0--but its a lot more work.
http://msdn.microsoft.com/en-us/magazine/cc163317.aspx#S7

http://msdn.microsoft.com/en-us/library/bb383977.aspx





Local Type Inference

he focus of this article will be on highlighting the local type inference feature that has been added to C# 3.0 and Visual Basic 9.0 languages. You'll touch on what it is, the syntax behind it, and why it is relevant to understand. You'll also touch on some examples of invalid uses because it can be just as helpful to examine what it is not to get a grasp on the concept.

Local Type Inference Defined

Local type inference is a language feature that allows you to define variables and use them without worrying about their true type. Local type inference is also interchangeably known as implicitly typed local variables. The burden is put on the respective language compiler to determine the type of a variable by inferring it from the expression assigned to the variable. The result is type safety while allowing you to write more relaxed code, which is required to support Language Integrated Query (LINQ).

Based on the description and a first glance of code, it is very easy to mistake type inference to be similar to defining everything as a type object or use of variants, which is heavily used in Visual Basic 6.0. This is entirely untrue and not what type inference is about. Type inferred variables are strongly typed. The type cannot be changed once it is assigned as could be done with a variant type so it does not involve any casting operations or the resulting performance implications. A strong type is assigned, but simply done so by the compiler based on the results of the expression assigned to the variable. The net effect is the true type isn't as readily apparent when reading code, but the Visual Studio IDE will tell you the type assigned along with the GetType() method will return a strong type at runtime.

There may be temptation over time to get lazy and let the compiler do the work for you by using type inference across the board. However, this is where the local part of local type inference comes into play. Type inference can only be used within a local scope where its type can be inferred by the expression assignment. Type inference cannot be applied to any of the following:

  • Cannot be a part of a member property declaration on a class, struct, or interface
  • Cannot be used in a parameter list on a method
  • Cannot be a return type for a method
  • Cannot be defined without a right hand assignment expression
  • Cannot reassign to be a different type once type has been inferred

Local Type Inference in C# 3.0

C# 3.0 implements local type inference through the var keyword in place of a specific type in a variable declaration.

The sample code below demonstrates the syntax for local type inference in C#. I created a new Windows console project to hold the code. Visual Studio 2008 Beta 2 was used to create the examples contained within.


namespace CodeGuru.TypeInference
{
class Program
{
static void Main(string[] args)
{
int a = 5;
var b = a; // int
var x = 5.5M; // double
var s = "string"; // string
var l = s.Length; // int

Console.WriteLine("value of b is {0} and type is {1}",
b, b.GetType().ToString());
Console.WriteLine("type of x is {0}", x.GetType().ToString());
Console.WriteLine("type of s is {0}", s.GetType().ToString());
Console.WriteLine("type of l is {0}", l.GetType().ToString());

Console.ReadLine();
}
}
)

It can be just as useful at times to look at examples where something does not apply. The following sample C# code demonstrates situations in which local type inference cannot be used. The code that is listed below will result in six different compile errors based on invalid usage and intentionally will not compile.

namespace CodeGuru.TypeInference
{
class Program
{
var test = "invalid use"; // invalid in member declaration

// Invalid as parameter
public void TryAsParameter(var parm)
{
}

// Invalid as return type
public var TryAsReturnType()
{
return "invalid use";
}

public void TryInvalidLocalUse()
{
var local1; // must be initialized
var local2 = null; // can't infer type from null

var local3 = 5; // valid use
local3 = "change type"; // can't change type
}
}


}

Local Type Inference in Visual Basic 9.0



Using local type inference in Visual Basic is more likely to be
misleading because it can appear as if it matches the behavior of Option Strict Off. As with C#, you still get a strong type despite the appearances. The syntax in Visual Basic is to omit the As Type part of the variable declaration. This will work just fine with Option Strict On and it is encouraged to continue use of Option Strict On to ensure variant types are not allowed and avoids the undesired boxing and unboxing.



Visual Basic allows you to turn local type inference on and off. There is Option Infer On and Option Infer Off that will enable or disable local type inference respectively. It is on by default.



The sample code below will demonstrate the syntax for local type inference in Visual Basic.



Option Strict On

Module Module1

Sub Main()

Dim As Integer = 5
Dim b = a ' int
Dim x = 5.5 ' double
Dim s = "string" ' string
Dim l = s.Length() ' int

Console.WriteLine("value of b is {0} and type is {1}", b, _
b.GetType().ToString())
Console.WriteLine("type of x is {0}",
x.GetType().ToString())
Console.WriteLine("type of s is {0}",
s.GetType().ToString())
Console.WriteLine("type of l is {0}",
l.GetType().ToString())

Console.ReadLine()

End Sub

End Module



As with the C# example, it can be just as beneficial to demonstrate
where local type inference cannot be used. The following sample code
demonstrates invalid attempts at using local type inference in Visual
Basic 9.0. It is important to note this code will not compile.



Module Module1

Dim test = "invalid use" ' invalid in member declaration

' Invalid as parameter
Sub TryAsParameter(ByVal parm)
End Sub


Sub Main()
Dim local ' must be initialized

Dim local3 = 5 ' valid use
local3 = "change type" ' cannot change type
End Sub

End Module



Summary



This article covered the local type inference language feature. You
examined what it is along with the syntax using examples of how it can
and cannot be used. Type inference is one of the language features
along with extension methods, partial methods, and others that enable
Language Integrated Queries (LINQ) to be possible, so it is important
to understand how type inference works and what it is not.

Read Data From an Excel File in ASP.NET

In this article, we will see how to display data from an Excel spreadsheet using ASP.NET. We will connect to a Microsoft Excel workbook using the OLEDB.NET data provider, extract data and then display the data in a GridView. Let us get started.
Step 1: Open Visual Studio > File > New >Website > Under Templates, click ASP.NET WebSite and choose either Visual C# or Visual Basic as the language. Select a location and click Ok.
Step 2: We will create two excel sheets and add them to the project. One excel sheet will be created in Office 2003(.xls) and the other one using Office 2007(.xlsx or .xls) . Add 4 columns called EID, EName, Age and City to the ‘Sheet1’. Also add some data into the columns. Once these excel files are created, add them to your project. To add them to the project, right click project > Add Existing Item > Add the two excel files.
Step 3: We will now create a web.config file to store the connection string information. Right click project > Add New Item > Web.config. Add the following entries to the file.


<connectionStrings>
<add name="xls"connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Sample1.xls;Extended Properties=Excel 8.0"/>
<add name="xlsx"connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Sample.xlsx;Extended Properties=Excel 12.0"/>
As you can observe, the connection string for xlsx (Excel 2007) contains Microsoft.ACE.OLEDB.12.0 as the provider. This is the new Access database engine OLE DB driver and is also capable of reading Excel 2003.
Step 4: Add a GridView to the Default.aspx page. We will extract data from the excel file and bind it to the GridView.
Step 5: Let us now create a connection to the excel file and extract data from it. Before that add a reference to System.Data.OleDb;
C#
protected void Page_Load(object sender, EventArgs e)
{
string connString = ConfigurationManager.ConnectionStrings["xls"].ConnectionString;
// Create the connection object
OleDbConnection oledbConn = new OleDbConnection(connString);
try
{
// Open connection
oledbConn.Open();
// Create OleDbCommand object and select data from worksheet Sheet1
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [Sheet1$]", oledbConn);
// Create new OleDbDataAdapter
OleDbDataAdapter oleda = new OleDbDataAdapter();
oleda.SelectCommand = cmd;
// Create a DataSet which will hold the data extracted from the worksheet.
DataSet ds = new DataSet();
// Fill the DataSet from the data extracted from the worksheet.
oleda.Fill(ds, "Employees");
// Bind the data to the GridView
GridView1.DataSource = ds.Tables[0].DefaultView;
GridView1.DataBind();
}
catch
{
}
finally
{
// Close connection
oledbConn.Close();
}
}
VB.NET
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
Dim connString As String = ConfigurationManager.ConnectionStrings("xls").ConnectionString
' Create the connection object
Dim oledbConn As OleDbConnection = New OleDbConnection(connString)
Try
' Open connection
oledbConn.Open()
' Create OleDbCommand object and select data from worksheet Sheet1
Dim cmd As OleDbCommand = New OleDbCommand("SELECT * FROM [Sheet1$]", oledbConn)
' Create new OleDbDataAdapter
Dim oleda As OleDbDataAdapter = New OleDbDataAdapter()
oleda.SelectCommand = cmd
' Create a DataSet which will hold the data extracted from the worksheet.
Dim ds As DataSet = New DataSet()
' Fill the DataSet from the data extracted from the worksheet.
oleda.Fill(ds, "Employees")
' Bind the data to the GridView
GridView1.DataSource = ds.Tables(0).DefaultView
GridView1.DataBind()
Catch
Finally
' Close connection
oledbConn.Close()
End Try
End Sub
All set!! Run the application and see the data getting displayed in the GridView. If you want to target the Excel 2007 sheet, just change xls to xlsx in the ConfigurationManager.ConnectionString.
I hope this article was useful and I thank you for viewing it.
If you liked the article, Subscribe to my RSS Feed.
}
}




Thats it




Welcome