You are on page 1of 23

Oz Barzilay

 Implicitly typed local variables


 Implicitly typed arrays
 Auto Implemented Properties
 Extension methods
 Lambda expressions
 Object initializers
 Anonymous types
 Query expressions
 Expression trees
 C# 3.0 introduces a new keyword called "var".
This new keyword enables you to declare a
variable whose type is implicitly inferred from
the expression used to initialize the variable.

 For example, consider the following line of code:

var age = 30;

 The preceding line initializes the variable age to


value 30 and automatically gives it the type of
integer.
 Note that the variable age is a strongly typed
variable (integer in this case) and doesn't carry
the overhead of a generic object type such as
System.Object class.
 The declarator must include an initializer:
ERROR: var x;

 The initializer must be an expression.


The initializer cannot be an object or collection
initializer by itself, but it can be a new expression
that includes an object or collection initializer.
ERROR: var y = {1, 2, 3};

 The compile-time type of the initializer expression


cannot be the null type.
ERROR: var z = null;

 If the local variable declaration includes multiple


declarators, the initializers must all have the same
compile-time type.
ERROR: var t = “Hello; t = 3;
 In addition to implicitly declaring
variables, you can also use the var
keyword for declaring arrays as well
 var numbers = new[] { 1, 2, 3, 4, 5}; // int[]
var names = new[] { "Dave", Doug, "Jim" }; //
string[]
 The compiler infers the type of the
array elements at compile-time by
examining the values from the
initialization expression.
 Whenever you declare a class, most of the times the
class is used only as a placeholder with getters and
setters for holding property values without any
additional logic.
 And now:
 public class Person
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; private set; }
    public string FullName
    {
        get
        {
            return FirstName + " " + LastName;
        }
    }
}
 Extension methods are static methods that
can be invoked using instance method syntax.
In effect, extension methods make it possible to
extend existing types and constructed types
with additional methods.
 public static class ExtermalObjectMethods {
public static bool IsNull(this object obj)
{
return obj == null;
}
}
 Import ExtermalObjectMethods ;
object o = null;
if (o.IsNull() )
{
Console.WriteLine("Object is null");
}
 Like anonymous methods (delegate),
only with an even easier syntax.
 A lambda expression is written as
parameters => expression
 Example:
var i = 1;
Func<int,int> f = j => j + 1;
Console.Out.WriteLine(f(i));
 namespace System.Query
{
public static class Sequence
{
public static IEnumerable<S>
Select<T,S>(
this IEnumerable<T> source,
Func<T,S> selector)
{
foreach (T element in source)
yield return
selector(element);
}
}
}
 List<Customer> customers =
GetCustomerList();
IEnumerable<string> names =
 Func<INT , int> fib = null;
fib = n => n > 1 ? fib(n - 1) + fib(n -
2) : n;
 Console.Out.WriteLine(fib(90));
//10946

 Not good example though, because


recursion is VERY memory
consuming, in compare to iteration.
 Should use memoizing if you still
 An object initializer specifies values for one or
more fields or properties of an object.
 Example:
 public class Point
{
int x, y;
public int X { get { return x; } set { x =
value; } }
public int Y { get { return y; } set { y =
value; } }
}
 An instance of Point can be created an initialized
as follows:
var a = new Point { X = 0, Y = 1 };
 which has the same effect as
var a = new Point();
a.X = 0;
 A collection initializer specifies the elements of a
collection.
 Example:
 public class Contact
{
string name;
List<string> phoneNumbers = new
List<string>();
public string Name
{
get { return name; }
set { name = value; }
}
public List<string> PhoneNumbers
{
get { return phoneNumbers; }
}
}
 A List<Contact> can be created and initialized as follows:
 var contacts = new List<Contact> {
new Contact { Name = "Chris Smith",
PhoneNumbers = { "206-555-0101", "425-
882-8080" }},
new Contact {Name = "Bob Harris", PhoneNumbers =
{ "650-555-0199" }
}
};
 which has the same effect as
 var contacts = new List<Contact>();
var __c1 = new Contact();
__c1.Name = "Chris Smith";
__c1.PhoneNumbers.Add("206-555-0101");
__c1.PhoneNumbers.Add("425-882-8080");
contacts.Add(__c1);
var __c2 = new Contact();
__c2.Name = "Bob Harris";
__c2.PhoneNumbers.Add("650-555-0199");
contacts.Add(__c2);
 where __c1 and __c2 are temporary variables that are otherwise
invisible and inaccessible
 anonymous types allow you to create
a type on-the-fly at compile time.
 The newly created type has public
properties and backing fields defined
for the members you initialize during
construction:
 var obj=
new{ID=1,FirstName=“Oz",LastNam
e=“Bar"};
 Passing of an Anonymous Type is by
first cast the type to object
 Query expressions provide a
language integrated syntax for queries
that is similar to relational and
hierarchical query languages such as
SQL.
 The translation from query expressions
to method invocations is a syntactic
mapping that occurs before any type
binding or overload resolution has been
performed.
 query expressions are translated into
invocations of methods named Where,
Select, SelectMany, OrderBy,
OrderByDescending, ThenBy,
ThenByDescending, and GroupBy
 List<Person> list = new List<Person>
{
new Person { FirstName = "oz" },
new Person { FirstName = "Golan"
} };

 IEnumerable<string> firstNames =
from people in list orderby
people.FirstName select
people.FirstName;
// == {”Golan”, “Oz”}

 Compiler Conversion =
list.OrderBy(people =>
people.FirstName).Select(people =>
 An example for creating new
anonymous type object with LINQ
Multiple generators:
 from c in customers
where c.City == "London"
from o in c.Orders
where o.OrderDate.Year == 2005
select new { c.Name, o.OrderID,
o.Total }
//= {{“Oz”,123456,7},
{“Golan”,78910,8}}
 Expression Tree is the feature which
enables you to write function which can
be complied on-demand basis.
 It stores the function in form of
structured data rather than executable
code
 Expression<Func<int, int>> e = x =>
x * 5;
 And if you want to invoke the above
exp you need to compile it first:
var f = e.Compile();
 And execute:
 Expression<Func<int, bool>> exprTree = num => num <
5;

 // Decompose the expression tree.


 ParameterExpression param =
(ParameterExpression)exprTree.Parameters[0];
 BinaryExpression operation =
(BinaryExpression)exprTree.Body;
 ParameterExpression left =
(ParameterExpression)operation.Left;
 ConstantExpression right =
(ConstantExpression)operation.Right;

 Console.WriteLine("Decomposed expression: {0} => {1}


{2} {3}",
 param.Name, left.Name, operation.NodeType,
right.Value);
 var q = from o in orders, c in customers
where o.ShipCity == "London" &&
(o.CustomerID == c.CustomerID) select
new { o.OrderDate, c.CompanyName,
c.ContactTitle, c.ContactName };
 Equals to:
var q = orders.Where(o => o.ShipCity
== "London").SelectMany( o =>
customers.Where(c => o.CustomerID
== c.CustomerID). Select(c => new
{ o.OrderDate, c.CompanyName,
c.ContactTitle, c.ContactName }));
 'SELECT [t1].[CompanyName],
[t1].[ContactName], [t1].[ContactTitle],
[t0].[OrderDate]
FROM [Orders] AS [t0], [Customers] AS
[t1]
WHERE ([t0].[ShipCity] = @p0) AND
([t0].[CustomerID] =
[t1].[CustomerID])', N'@p0 nvarchar(6)',
@p0 = N'London'
 It has generated a single query that
returns exactly the data we require in
the form we want. Not only is the join
on the Orders and Customers table
being done in the DB where it should
be, the query has also been suitably
1. http://www.15seconds.com/issue/080228.htm
2. http://www.codeproject.com/KB/cs/Introductio
3. C# Spec By Microsoft
4. http://www.hanselman.com/blog/TheWeeklySo
5. http://blogs.msdn.com/wriju/archive/2007/04/
6. http://msdn.microsoft.com/en-us/library/bb397
7. http://www.interact-sw.co.uk/iangblog/2005/0
 public static Func<Int32, Int32> Memoize(Func<Int32,
Int32> func)
 {
 Dictionary<Int32, Int32> cache = new
Dictionary<Int32, Int32>();
 Int32 result;
 return key => cache.TryGetValue(key, out result)
 ?
 result
 :
 cache[key] = result = func(key);
 }
 Func<Int32, Int32> fib = null;
 fib = n => n > 1 ? fib(n - 1) + fib(n - 2) : n;
 fib = Memoize(fib);
 Console.Out.WriteLine(fib(90));

You might also like