Saturday, March 27, 2010

Few Tips on Index Optimization

  • Consider creating index on column(s) frequently used in the WHERE, ORDER BY, and GROUP BY clauses.
    These column(s) are best candidates for index creating. You should analyze your queries very attentively to avoid creating not useful indexes.


  • *****

  • Keep your indexes as narrow as possible.
    Because each index take up disk space try to minimize the index key's size to avoid using superfluous disk space. This reduces the number of reads required to read the index and boost overall index performance.


  • *****

  • Drop indexes that are not used.
    Because each index take up disk space and slow the adding, deleting, and updating of rows, you should drop indexes that are not used. You can use Index Wizard to identify indexes that are not used in your queries.


  • *****

  • Try to create indexes on columns that have integer values rather than character values.
    Because the integer values usually have less size then the characters values size (the size of the int data type is 4 bytes, the size of the bigint data type is 8 bytes), you can reduce the number of index pages which are used to store the index keys. This reduces the number of reads required to read the index and boost overall index performance.


  • *****

  • Limit the number of indexes, if your application updates data very frequently.
    Because each index take up disk space and slow the adding, deleting, and updating of rows, you should create new indexes only after analyze the uses of the data, the types and frequencies of queries performed, and how your queries will use the new indexes. In many cases, the speed advantages of creating the new indexes outweigh the disadvantages of additional space used and slowly rows modification. However, avoid using redundant indexes, create them only when it is necessary. For read-only table, the number of indexes can be increased.


  • *****

  • Check that index you tried to create does not already exist.
    Keep in mind that when you create primary key constraint or unique key constraints SQL Server automatically creates index on the column(s) participate in these constraints. If you specify another index name, you can create the indexes on the same column(s) again and again.


  • *****

  • Create clustered index instead of nonclustered to increase performance of the queries that return a range of values and for the queries that contain the GROUP BY or ORDER BY clauses and return the sort results.
    Because every table can have only one clustered index, you should choose the column(s) for this index very carefully. Try to analyze all your queries, choose most frequently used queries and include into the clustered index only those column(s), which provide the most performance benefits from the clustered index creation.


  • *****

  • Create nonclustered indexes to increase performance of the queries that return few rows and where the index has good selectivity.
    In comparison with a clustered index, which can be only one for each table, each table can have as many as 249 nonclustered indexes. However, you should consider nonclustered index creation as carefully as the clustered index, because each index take up disk space and drag on data modification.


  • *****

  • Create clustered index on column(s) that is not updated very frequently.
    Because the leaf node of a nonclustered index contains a clustered index key if the table has clustered index, then every time that a column used for a clustered index is modified, all of the nonclustered indexes must also be modified.


  • *****

  • Create clustered index based on a single column that is as narrow as possibly.
    Because nonclustered indexes contain a clustered index key within their leaf nodes and nonclustered indexes use the clustered index to locate data rows, creating clustered index based on a single column that is as narrow as possibly will reduce not only the size of the clustered index, but all nonclustered indexes on the table also.


  • *****

  • Avoid creating a clustered index based on an incrementing key.
    For example, if a table has surrogate integer primary key declared as IDENTITY and the clustered index was created on this column, then every time data is inserted into this table, the rows will be added to the end of the table. When many rows will be added a "hot spot" can occur. A "hot spot" occurs when many queries try to read or write data in the same area at the same time. A "hot spot" results in I/O bottleneck.
    Note. By default, SQL Server creates clustered index for the primary key constraint. So, in this case, you should explicitly specify NONCLUSTERED keyword to indicate that a nonclustered index is created for the primary key constraint.


  • *****

  • Create a clustered index for each table.
    If you create a table without clustered index, the data rows will not be stored in any particular order. This structure is called a heap. Every time data is inserted into this table, the row will be added to the end of the table. When many rows will be added a "hot spot" can occur. To avoid "hot spot" and improve concurrency, you should create a clustered index for each table.


  • *****

  • Don't create index on column(s) which values has low selectivity.
    For example, don't create an index for columns with many duplicate values, such as "Sex" column (which has only "Male" and "Female" values), because in this case the disadvantages of additional space used and slowly rows modification outweigh the speed advantages of creating a new index.


  • *****

  • If you create a composite (multi-column) index, try to order the columns in the key as to enhance selectivity, with the most selective columns to the leftmost of the key.
    The order of the columns in a composite (multi-column) index is very important. This can increase the chance the index will be used.


  • *****

  • If you create a composite (multi-column) index, try to order the columns in the key so that the WHERE clauses of the frequently used queries match the column(s) that are leftmost in the index.
    The order of the columns in a composite (multi-column) index is very important. The index will be used to evaluate a query only if the leftmost index key's column are specified in the WHERE clause of the query. For example, if you create composite index such as "Name, Age", then the query with the WHERE clause such as "WHERE Name = 'Alex'" will use the index, but the query with the WHERE clause such as "WHERE Age = 28" will not use the index.


  • *****

  • If you need to join several tables very frequently, consider creating index on the joined columns.
    This can significantly improve performance of the queries against the joined tables.


  • *****

  • Consider creating a surrogate integer primary key (identity, for example).
    Every table must have a primary key (a unique identifier for a row within a database table). A surrogate primary key is a field that has a unique value but has no actual meaning to the record itself, so users should never see or change a surrogate primary key. Some developers use surrogate primary keys, others use data fields themselves as the primary key. If a primary key consists of many data fields and has a big size, consider creating a surrogate integer primary key. This can improve performance of your queries.


  • *****

  • Consider creating the indexes on all the columns, which referenced in most frequently used queries in the WHERE clause which contains the OR operator.
    If the WHERE clause in the query contains an OR operator and if any of the referenced columns in the OR clause are not indexed, then the table or clustered index scan will be made. In this case, creating the indexes on all such columns can significantly improve your queries performance.


  • *****

  • If your application will perform the same query over and over on the same table, consider creating a covering index including columns from this query.
    A covering index is an index, which includes all of the columns referenced in the query. So the creating covering index can improve performance because all the data for the query is contained within the index itself and only the index pages, not the data pages, will be used to retrieve the data. Covering indexes can bring a lot of performance to a query, because it can save a huge amount of I/O operations.


  • *****

  • Use the DBCC DBREINDEX statement to rebuild all the indexes on all the tables in your database periodically (for example, one time per week at Sunday) to reduce fragmentation.
    Because fragmented data can cause SQL Server to perform unnecessary data reads and the queries performance against the heavy fragmented table can be very bad, you should periodically rebuild all indexes to reduce fragmentation. Try to schedule the DBCC DBREINDEX statement during CPU idle time and slow production periods.


  • *****

  • Use the DBCC INDEXDEFRAG statement to defragment clustered and secondary indexes of the specified table or view.
    The DBCC INDEXDEFRAG statement is a new SQL Server 2000 command, which was not supported in the previous versions. Unlike DBCC DBREINDEX, DBCC INDEXDEFRAG does not hold locks long term and thus will not block running queries or updates. So, try to use the DBCC INDEXDEFRAG command instead of DBCC DBREINDEX, whenever possible.


  • *****

  • Consider using the SORT_IN_TEMPDB option when you create an index and when tempdb is on a different set of disks than the user database.
    The SORT_IN_TEMPDB option is a new SQL Server 2000 feature, which was not supported in the previous versions. When you create an index with the SORT_IN_TEMPDB option, SQL Server uses the tempdb database, instead of the current database, to sort data during the index creation. Using this option can reduce the time it takes to create an index, but increases the amount of disk space used to create an index.


  • *****

  • Use the SQL Server Profiler Create Trace Wizard with "Identify Scans of Large Tables" trace to determine which tables in your database may need indexes.
    This trace will show which tables are being scanned by queries instead of using an index.


  • *****

Few Tips on Stored Procedures Optimization

  • Use stored procedures instead of heavy-duty queries.
    This can reduce network traffic, because your client will send to server only stored procedure name (perhaps with some parameters) instead of large heavy-duty queries text. Stored procedures can be used to enhance security and conceal underlying data objects also. For example, you can give the users permission to execute the stored procedure to work with the restricted set of the columns and data.


  • *****

  • Include the SET NOCOUNT ON statement into your stored procedures to stop the message indicating the number of rows affected by a Transact-SQL statement.
    This can reduce network traffic, because your client will not receive the message indicating the number of rows affected by a Transact-SQL statement.


  • *****

  • Call stored procedure using its fully qualified name (If Possible).
    The complete name of an object consists of four identifiers: the server name, database name, owner name, and object name. An object name that specifies all four parts is known as a fully qualified name. Using fully qualified names eliminates any confusion about which stored procedure you want to run and can boost performance because SQL Server has a better chance to reuse the stored procedures execution plans if they were executed using fully qualified names.


  • *****

  • Consider returning the integer value as an RETURN statement instead of an integer value as part of a recordset.
    The RETURN statement exits unconditionally from a stored procedure, so the statements following RETURN are not executed. Though the RETURN statement is generally used for error checking, you can use this statement to return an integer value for any other reason. Using RETURN statement can boost performance because SQL Server will not create a recordset.


  • *****

  • Don't use the prefix "sp_" in the stored procedure name if you need to create a stored procedure to run in a database other than the master database.
    The prefix "sp_" is used in the system stored procedures names. Microsoft does not recommend to use the prefix "sp_" in the user-created stored procedure name, because SQL Server always looks for a stored procedure beginning with "sp_" in the following order: the master database, the stored procedure based on the fully qualified name provided, the stored procedure using dbo as the owner, if one is not specified. So, when you have the stored procedure with the prefix "sp_" in the database other than master, the master database is always checked first, and if the user-created stored procedure has the same name as a system stored procedure, the user-created stored procedure will never be executed.


  • *****

  • Use the sp_executesql stored procedure instead of the EXECUTE statement.
    The sp_executesql stored procedure supports parameters. So, using the sp_executesql stored procedure instead of the EXECUTE statement improve readability of your code when there are many parameters are used. When you use the sp_executesql stored procedure to executes a Transact-SQL statements that will be reused many times, the SQL Server query optimizer will reuse the execution plan it generates for the first execution when the change in parameter values to the statement is the only variation.


  • *****

  • Use sp_executesql stored procedure instead of temporary stored procedures.
    Microsoft recommends to use the temporary stored procedures when connecting to earlier versions of SQL Server that do not support the reuse of execution plans. Applications connecting to SQL Server 7.0 or SQL Server 2000 should use the sp_executesql system stored procedure instead of temporary stored procedures to have a better chance to reuse the execution plans.


  • *****

  • If you have a very large stored procedure, try to break down this stored procedure into several sub-procedures, and call them from a controlling stored procedure.
    The stored procedure will be recompiled when any structural changes were made to a table or view referenced by the stored procedure (for example, ALTER TABLE statement), or when a large number of INSERTS, UPDATES or DELETES are made to a table referenced by a stored procedure. So, if you break down a very large stored procedure into several sub-procedures, you get chance that only a single sub-procedure will be recompiled, but other sub-procedures will not.


  • *****

  • Try to avoid using temporary tables inside your stored procedure.
    Using temporary tables inside stored procedure reduces the chance to reuse the execution plan.


  • *****

  • Try to avoid using DDL (Data Definition Language) statements inside your stored procedure.
    Using DDL statements inside stored procedure reduces the chance to reuse the execution plan.


  • *****

  • Add the WITH RECOMPILE option to the CREATE PROCEDURE statement if you know that your query will vary each time it is run from the stored procedure.
    The WITH RECOMPILE option prevents reusing the stored procedure execution plan, so SQL Server does not cache a plan for this procedure and the procedure is recompiled at run time. Using the WITH RECOMPILE option can boost performance if your query will vary each time it is run from the stored procedure because in this case the wrong execution plan will not be used.


  • *****

  • Use SQL Server Profiler to determine which stored procedures has been recompiled too often.
    To check the stored procedure has been recompiled, run SQL Server Profiler and choose to trace the event in the "Stored Procedures" category called "SP:Recompile". You can also trace the event "SP:StmtStarting" to see at what point in the procedure it is being recompiled. When you identify these stored procedures, you can take some correction actions to reduce or eliminate the excessive recompilations.


  • *****

Saturday, March 20, 2010

Mail merge from .Net (C#)

Here are the two nice links from MSDN for Office developer:
How to automate Word with Visual Basic to create a Mail Merge Sample Link 1

How to automate Microsoft Word to perform Mail Merge from Visual C# Sample Link 2

The best Sample code which I like is available here with step by step: Sample Link 3

Sample Code I used for my application. My requirement was to send an eFax with some text body which will load from another doc file.

Step1: Created a word template file with tow merge fields ('Header' and 'Footer') and a bookmark with name 'DocumentContents'.
Step2: Open the template file and set the header and footer
Step3: Place the source file contents to the bookmark
Step4: Save the modified template file as output file

Code:
public void Merge(string templateFile, string sourceFile, string destFile)
{
if(!File.Exists(templateFile))
{
throw new FileNotFoundException(string.Format("Template file '{0}' does not exist",templateFile));
}

if (!File.Exists(sourceFile))
{
throw new FileNotFoundException(string.Format("Source file '{0}' does not exist", sourceFile));
}

if (File.Exists(destFile))
{
File.Delete(destFile);
}

object oFalse = false;
object oMissing = Missing.Value;
Application oWord = new Application();
Document oWordDoc = new Document();
try
{
oWord.Visible = true;
object oTemplatePath = templateFile;
oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing);

foreach (Field myMergeField in oWordDoc.Fields)
{
Microsoft.Office.Interop.Word.Range rngFieldCode = myMergeField.Code;
String fieldText = rngFieldCode.Text;

// ONLY GETTING THE MAILMERGE FIELDS
if (fieldText.StartsWith(" MERGEFIELD"))
{
// THE TEXT COMES IN THE FORMAT OF
// MERGEFIELD MyFieldName \\* MERGEFORMAT
Int32 endMerge = fieldText.IndexOf("\\");
Int32 fieldNameLength = fieldText.Length - endMerge;
String fieldName = fieldText.Substring(11, endMerge - 11).Trim();

if (fieldName == "Header")
{
myMergeField.Select();
oWord.Selection.TypeText("Set Header of the File");
}

if (fieldName == "Footer")
{
myMergeField.Select();
oWord.Selection.TypeText("Set Footer of the File");
}
}
}

object oBookMark = "DocumentContents";
String oFilePath = sourceFile;
oWordDoc.Bookmarks.get_Item(ref oBookMark).Range.InsertFile(oFilePath, ref oMissing, ref oFalse, ref oFalse, ref oFalse);

Object oSaveAsFile = (Object)destFile;
oWordDoc.SaveAs(ref oSaveAsFile, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing);
}
finally
{
oWordDoc.Close(ref oFalse, ref oMissing, ref oMissing);
oWord.Quit(ref oMissing, ref oMissing, ref oMissing);
Marshal.ReleaseComObject(oWordDoc);
}
}

Thursday, November 19, 2009

Contextual Keywords in C#

Contextual Keywords in C#

A contextual keyword is used to provide a specific meaning in the code, but it is not a reserved word in C#. This will give some understanding on different contextual keywords and make you comfortable while using those...

yield:
Used in an iterator block to return a value to the enumerator object or to signal the end of iteration.


Use of this construct is vital for LINQ. Yield return allows one enumerable function to be implemented in terms of another. It allows us to write functions that return collections that exhibit lazy behavior. This allows LINQ and LINQ to XML to delay execution of queries until the latest possible moment. it allows queries to be implemented in such a way that LINQ and LINQ to XML do not need to assemble massive intermediate results of queries. Without the avoidance of intermediate results of queries, the system would rapidly become unwieldy and unworkable.

The following two small programs demonstrate the difference in implementing a collection via the IEnumerable interface, and using yield return in an iterator block.

With this first example, you can see that there is a lot of plumbing that you have to write. You have to implement a class that derives from IEnumerable, and another class that derives from IEnumerator. The GetEnumerator() method in MyListOfStrings returns an instance of the class that derives from IEnumerator. But the end result is that you can iterate through the collection using foreach.

public class MyListOfStrings : IEnumerable
{
private string[] _strings;
public MyListOfStrings(string[] sArray)
{
_strings = new string[sArray.Length];

for (int i = 0; i < sArray.Length; i++)
{
_strings[i] = sArray[i];
}
}

public IEnumerator GetEnumerator()
{
return new StringEnum(_strings);
}
}

public class StringEnum : IEnumerator
{
public string[] _strings;

// Enumerators are positioned before the first element
// until the first MoveNext() call.
int position = -1;

public StringEnum(string[] list)
{
_strings = list;
}

public bool MoveNext()
{
position++;
return (position < _strings.Length);
}

public void Reset()
{
position = -1;
}

public object Current
{
get
{
try
{
Console.WriteLine("about to return {0}", _strings[position]);
return _strings[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}

class Program
{
static void Main(string[] args)
{
string[] sa = new[] {
"aaa",
"bbb",
"ccc"
};

MyListOfStrings p = new MyListOfStrings(sa);

foreach (string s in p)
Console.WriteLine(s);
}
}

Using the yield return keywords, the equivalent in functionality is as follows. This code is attached to this page:

class Program
{
public static IEnumerable MyListOfStrings(string[] sa)
{
foreach (var s in sa)
{
Console.WriteLine("about to yield return");
yield return s;
}
}

static void Main(string[] args)
{
string[] sa = new[] {
"aaa",
"bbb",
"ccc"
};

foreach (string s in MyListOfStrings(sa))
Console.WriteLine(s);
}
}

As you can see, this is significantly easier.

This isn't as magic as it looks. When you use the yield contextual keyword, what happens is that the compiler automatically generates an enumerator class that keeps the current state of the iteration. This class has four potential states: before, running, suspended, and after. This class has Reset and MoveNext methods, and a Current property. When you iterate through a collection that is implemented using yield return, you are moving from item to item in the enumerator using the MoveNext method. The implementation of iterator blocks is fairly involved. A technical discussion of iterator blocks can be found in the C# specifications.

Yield return is very important when implementing our own query operators (which we will want to do sometimes).

There is no counterpart to the yield keyword in Visual Basic 9.0, so if you are implementing a query operator in Visual Basic 9.0, you must use the approach where you implement IEnumerable and IEnumerator.

One of the important design philosophies about the LINQ and LINQ to XML technologies is that they should not break existing programs. Adding new keywords will break existing programs if the programs happen to use the keyword in a context that would be invalid. Therefore, some keywords are added to the language as contextual keywords. This means that when the keyword is encountered at specific places in the program, it is interpreted as a keyword, whereas when the keyword is encountered elsewhere, it may be interpreted as an identifier. Yield is one of these keywords. When it is encountered before a return or break keyword, it is interpreted by the compiler as appropriate, and the new semantics are applied. If the program was written in C# 1.0 or 1.1, and it contained an identifier named yield, then the identifier continues to be parsed correctly by the compiler, and the program is not made invalid by the language extensions.

Wednesday, November 18, 2009

Extension Methods

Extension methods are special methods that, while they are not part of a data type, you can call them as though they were part of the data type. Extension methods are a feature of C# 3.0.

Writing Extension Methods
To write an extension method, you do the following:

· Define a public static class.
· Define a public static method in the class where the first argument is the data type for which you want the extension method.
· Use the this keyword on the first argument to your public static method. The this keyword denotes the method as an extension method.

This special syntax is actually simply a natural extension of what you do normally when you want to make a utility method for a class that you don't want to (or can't) extend. A common pattern when you want to write a utility method is to define a static method that takes an instance of the class as the first parameter. This is exactly what an extension method is - the only difference is that you can then write a call to the method as though it were part of the class, and the compiler will find and bind to the extension method.

Note that the following class does not define a PrintIt method:

public class MyClass
{
public int IntField;
public MyClass(int arg)
{
IntField = arg;
}
}

This static class defines an extension method for the MyClass class:

public static class MyClassExtension
{
public static void PrintIt(this MyClass arg)
{
Console.WriteLine("IntField:{0}", arg.IntField);
}
}

You can now call the PrintIt method as though it were part of the class.

MyClass mc = new MyClass(10);
mc.PrintIt();

When you run this code, it outputs:

IntField:10

But the really cool thing is that you can write extension methods for a type that in and of itself, can't contain methods. The most important example of this is that you can write extension methods for interfaces. You could also write an extension method for an abstract class.

You can define extension methods for parameterized types as well as non-parameterized types. The standard query operators are almost all extension methods that are defined on IEnumerable.

Note that you can define your own extension methods for IEnumerable. When there isn't a standard query operator that does exactly what you want, you can write your own extension method. This is a powerful technique that adds expressiveness to your code.

When you are writing pure functional code, extension methods are important. There are times that writing extension methods on IEnumerable is the way that you want do things. We'll be using this technique sometimes when writing FP code.

Extension Methods are Vital for LINQ
Extension methods are an integral part of LINQ. Consider the following code that contains a LINQ query expression:

int[] source = new[] { 3, 6, 4, 8, 9, 5, 3, 1, 7, 0 };

IEnumerable query =
from i in source
where i >= 5
select i * 2;

foreach (var i in query)
Console.WriteLine(i);

This code is functionally identical to this:

int[] source = new[] { 3, 6, 4, 8, 9, 5, 3, 1, 7, 0 };

IEnumerable query =
source.Where(i => i >= 5)
.Select(i => i * 2);

foreach (var i in query)
Console.WriteLine(i);

In fact, you can see that there is a direct translation from the query expression to the same query that is expressed in method notation. I believe that in early versions of the C# 3.0 compiler, this translation was implemented almost like a macro. But in any case, queries that are implemented via method syntax rely, of course, on the extension methods that are included with the .NET framework, and hence query expressions also rely on them. It is the ability to write extension methods for generic interfaces that enables queries.

Lambda Expressions

A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types.
A lambda anonymous methods, that allows you to declare your method code inline instead of with a delegate function.

All lambda expressions use the lambda operator =>, which is read as "goes to". The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block. The lambda expression x => x * x is read "x goes to x times x."

(int x) => x + 1 // explicitly typed parameter
(y,z) => return y * z; // implicitly typed parameter

Note:
1. Lambdas are not allowed on the left side of the is or as operator.

To show lambda expressions in context, consider the problem where you have an array with 10 digits in it, and you want to filter for all digits greater than 5. In this case, you can use the Where extension method, passing a lambda expression as an argument to the Where method:

int[] source = new[] { 3, 8, 4, 6, 1, 7, 9, 2, 4, 8 };

foreach (int i in source.Where(x => x > 5))
Console.WriteLine(i);

First, a quick review of delegates:

Defining, Creating, and Using a Delegate
In C#, a delegate is a data structure that refers to either a static method, or an object and an instance method of its class. When you initialize a delegate, you initialize it with either a static method, or a class instance and an instance method.

The following code shows the definition of a delegate and a method that can be used to initialize the delegate:

// Defines a delegate that takes an int and returns an int
public delegate int ChangeInt(int x);

// Define a method to which the delegate can point
static public int DoubleIt(int x)
{
return x * 2;
}

Now, you can create and initialize an instance of the delegate, and then call it:

ChangeInt myDelegate = new ChangeInt(DelegateSample.DoubleIt);
Console.WriteLine("{0}", myDelegate(5));

This, as you would expect, writes 10 to the console.

Using an Anonymous Method
With C# 2.0, anonymous methods allow you to write a method and initialize a delegate in place:

ChangeInt myDelegate = new ChangeInt(
delegate(int x)
{
return x * 2;
}
);
Console.WriteLine("{0}", myDelegate(5));

Using a Lambda Expression
With Lambda expressions, the syntax gets even terser:

ChangeInt myDelegate = x => x * 2;
Console.WriteLine("{0}", myDelegate(5));

This lambda expression is an anonymous method that takes one argument x, and returns x * 2. In this case, the type of x and the type that the lambda returns are inferred from the type of the delegate to which the lambda is assigned.

If you wanted to, you could have specified the type of the argument, as follows:

ChangeInt myDelegate = (int x) => x * 2;
Console.WriteLine("{0}", myDelegate(5));

Using a Lambda with Two Arguments
When using the Standard Query Operators, on occasion, you need to write a lambda expression that takes two arguments.

If you have a delegate that takes two arguments:

// Defines a delegate that takes two ints and returns an int
public delegate int MultiplyInts(int arg, int arg2);

You can declare and initialize a delegate:

MultiplyInts myDelegate = (a, b) => a * b;
Console.WriteLine("{0}", myDelegate(5, 2));

Statement Lambda Expressions
You can write a more complicated lambda expression using statements, enclosing the statements in braces. If you use this syntax, you must use the return statement, unless the lambda returns void:

int[] source = new[] { 3, 8, 4, 6, 1, 7, 9, 2, 4, 8 };

foreach (int i in source.Where(
x =>
{
if (x <= 3)
return true;
else if (x >= 7)
return true;
return false;
}
))
Console.WriteLine(i);

Sometimes developers wonder how to pronounce the => token.

If the lambda expression is a predicate, expressing some condition: c => c.State == "WA" then the => can be spoken as "such that". In this example, you could say "c such that c dot state equals Washington". If the lambda expression is a projection, returning a new type: c => new XElement("CustomerID", c.CustomerID); then the => can be spoken as "becomes". In the above example, you could say "c becomes new XElement with a name of CustomerID and its value is c dot CustomerID". Or "maps to", or "evaluate to", as suggested in the comments below. But most often, I just say "arrow". J

A quick note: predicates are simply boolean expressions that are passed to some method that will use the boolean expression to filter something. A lambda expression used for projection takes one type, and returns a different type. More on both of these concepts later.

The Func Delegate Types
The framework defines a number of parameterized delegate types:

public delegate TR Func();
public delegate TR Func(T0 a0);
public delegate TR Func(T0 a0, T1 a1);
public delegate TR Func(T0 a0, T1 a1, T2 a2);
public delegate TR Func(T0 a0, T1 a1, T2 a2, T3 a3);

In the above delegate types, notice that if there is only one type parameter, it is the return type of the delegate. If there are two type parameters, the first type parameter is the type of the one and only argument, and the second type is the return type of the delegate, and so on. Many of the standard query operators (which are just methods that you call) take as an argument a delegate of one of these types.

Expression Trees
Lambda expressions can also be used as expression trees. This is an interesting topic, but is not part of this discussion on writing pure functional transformations.

Friday, September 11, 2009

InternalsVisibleToAttribute (C#)

Today I am going to give an idea on internal visible attribute which was introduced in .NET 2.0. This feature is better than accessing non-public member using reflection. Before starting this topic it is better to take a look on the different access modifier available in C# which will give us a clear picture on this.

Access Modifiers:
-Public
The type or member can be accessed by any other code in the same assembly or another assembly that references it.

-Private
The type or member can only be accessed by code in the same class or struct.

-Protected
The type or member can only be accessed by code in the same class or struct, or in a derived class.

-Internal
The type or member can be accessed by any code in the same assembly, but not from another assembly.

-Protected Internal
The type or member can be accessed by any code in the same assembly, or by any derived class in another assembly.

Friend Assemblies:

The friend assemblies feature allows you to access internal members; private types and private members will remain inaccessible. To give an assembly (assembly B) access to another assembly's (assembly A's) internal types and members, use the InternalsVisibleToAttribute attribute in assembly A.

It is better to give an example to understand better:
1. Add a class libarary (with name 'A')
Code will looks:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace A
{

public class Class1
{
private int num1 = 1;
public int num2 = 2;
protected int num3 = 3;
internal protected int num4 = 4;
int num5 = 5;
}
}

2. Add another console application (With name 'B') bellow
3. Add the project reference 'A' to project 'B' and add the below code to program.cs file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using A;

namespace B
{
class Program
{
static void Main(string[] args)
{
Class1 obj = new Class1();
int n1 = obj.num1; //Compiler error
int n2 = obj.num2; //No error
int n3 = obj.num3; //Compiler error
int n4 = obj.num4; //Compiler error
int n5 = obj.num5; //Compiler error
}
}
}

3. Compile the both the project and watch carefully. We are able to access only num2 as its access modifier is public. Don't worry we will do some this which will allow to access num4
4. Add the below code line to AssemblyInfo.cs on project 'A'. which will tell the 'A' to allow 'B' to access his protected internal members
[assembly: InternalsVisibleTo("B")]
5. Now recompile the project and you will see:
int n1 = obj.num1; //Compiler error
int n2 = obj.num2; //No error
int n3 = obj.num3; //Compiler error
int n4 = obj.num4; //No error
int n5 = obj.num5; //Compiler error



We can also provide the public token key whiling specifying the assembly name to the assemblyinfo.cs. To do this you may need following:

This example shows how to make internal types and members available for assemblies that have strong names.

To generate the keyfile and display public key, use the following sequence of sn.exe commands (for more information, see Strong Name Tool (Sn.exe)):

sn -k friend_assemblies.snk // Generate strong name key

sn -p friend_assemblies.snk key.publickey // Extract public key from key.snk into key.publickey

sn -tp key.publickey // Display public key stored in file'key.publickey

Pass the keyfile to the compiler with /keyfile.

Example:
[assembly:InternalsVisibleTo("B, PublicKey=002400000480000094…")]

Enjoy..:):)