C# and .NET Framework 4.0

acceptableseashoreSecurity

Nov 5, 2013 (4 years and 1 month ago)

94 views

C# and .NET Framework 4.0

Casey Liss

Ironworks Consulting

BORING STUFF

Prerequisites


Understanding of .NET and C#


WinForms or Web


Assuming mid
-
level developer

Who Am I?


Senior Developer, Ironworks Consulting


Developing Professionally 6 Years


Technologies


SharePoint, Ektron


ASP.NET, WinForms


iPhone


Total Shill


Apple


.NET

cliss@ironworks.com

Twitter:
@caseyliss

http://underthehood.ironworks.com/

Who is Ironworks?


Founded 2001, headquartered in Richmond


~200 Employees


Project
-
based Technology Consulting Firm


Enterprise Content Management / Portal Integration


Business Intelligence


Enterprise Search


Web 2.0 & Social Media


PMO / Management Consulting


Web Strategy & Interactive User
-
Centric Design


Custom Integration
-

.NET, SQL, BizTalk, etc.


“Never fail a client”


C#/.NET 1.1


Managed


COM Interop


P/Invoke


C#/.NET 2.0


Generics


Static Classes


Anonymous Methods


Nullables


C# 3.0/.NET 3.5


LINQ


Initializers


Anonymous Types


Lambdas


Extension Methods


Automatic Properties

History Lesson

Enter C# 4.0


Duck Typing



Parallelization



Covariant Generics


Contravariant Generics


Optional Parameters


Named Arguments


COM Enhancements


Cleaner ASP.NET Markup


URL Routing in WebForms

What’s New?

QUACK, QUACK!

Old and Busted

class

Foo

{


public

string

Bar {
get
;
set
; }

}


class

Program

{


static

void

Main(
string
[] args)


{


object

foo =
Assembly
.GetExecutingAssembly().CreateInstance(
typeof
(
Foo
).FullName);


((
Foo
)foo).Bar =
"Hello"
;
// Annoying, ugly cast


}

}

Slightly Better

class

Foo

{


public

string

Bar {
get
;
set
; }

}


class

Program

{


static

void

Main(
string
[] args)


{


Foo

foo =
Assembly
.GetExecutingAssembly().CreateInstance(
typeof
(
Foo
).FullName)
as

Foo
;


if

(foo !=
null
)
// Annoying conditional


{


foo.Bar =
"Hello"
;


}


}

}


Runtime lookup


Walks like a duck, quacks like a duck...


dynamic


How?


Dynamic Language Runtime (DLR)


COM:
IDispatch


DLR:
IDynamicMetaObjectProvider

(or
DynamicObject
)


Other: Reflection

Dynamic Member Lookup (Duck Typing)

Slightly Better (Reprise)

class

Foo

{


public

string

Bar {
get
;
set
; }

}


class

Program

{


static

void

Main(
string
[] args)


{


Foo

foo =
Assembly
.GetExecutingAssembly().CreateInstance(
typeof
(
Foo
).FullName)
as

Foo
;


if

(foo !=
null
)
// Annoying conditional


{


foo.Bar =
"Hello"
;


}


}

}

New Hotness

class

Foo

{


public

string

Bar {
get
;
set
; }

}


class

Program

{


static

void

Main(
string
[] args)


{


dynamic

foo =

Assembly
.GetExecutingAssembly().CreateInstance(
typeof
(
Foo
).FullName);


foo.Bar =
"Hello"
;


}

}


Dynamically parsing XML


Dynamically creating XML


Obfuscation


Hatfields & McCoys

Um, okay. Why???

PrintLength(Array a);

PrintLength(string s);


Can these be combined?



Two different types


Can’t modify source


Both have same method


No common ancestor

Hatfields & McCoys

static

void

PrintLengthReallyBusted(
object

o)

{


if

(o
is

Array
)


{


Console
.WriteLine(
"Length of Array is {0}."
,


((
Array
)o).Length);


}


else

if

(o
is

string
)


{


Console
.WriteLine(
"Length of string is {0}."
,


((
string
)o).Length);


}


else


{


throw

new

ArgumentException
(
string
.Format(


"Don't know how to handle {0}!"
,


o !=
null

? o.GetType().Name :
"
--
null
--
"
));


}

}

Hatfields & McCoys: First Treaty

static

void

PrintLengthSemiBusted(
object

o)

{


PropertyInfo

pi = o.GetType().GetProperty(
"Length"
);


if

(pi !=
null
)


{


object

length = pi.GetValue(o,
null
);


if

(length !=
null
)


{


Console
.WriteLine(
"Length of {0} is {1}."
,


o.GetType().Name,


length);


}


}


else


{


throw

new

ArgumentException
(
string
.Format(


"Don't know how to handle {0}!"
,


o !=
null

? o.GetType().Name :
"
--
null
--
"
));


}

}

Hatfields & McCoys: Second Treaty

static

void

PrintLength(
dynamic

obj)

{


try


{


Console
.WriteLine(
"Length of object {0} is {1}."
,


obj.GetType().Name,


obj.Length);


}


catch

(MS.C#.RuntimeBinder.
RuntimeBinderException

e)


{


throw

new

ArgumentException
(
string
.Format(


"Don't know how to handle {0}!"
,


obj !=
null

? obj.GetType().Name :
"
--
null
--
"
),



e);


}

}

Hatfields & McCoys: Show me the new hotness!

dynamic
makes weird stuff possible:


static

void

Main(
string
[] args)

{


dynamic

dyn =
"Hello, world!"
;


Console
.WriteLine(
"{0}
-

{1}"
, dyn,dyn.GetType().Name);


dyn = 143;


Console
.WriteLine(
"{0}
-

{1}"
, dyn,dyn.GetType().Name);

}



Trippy, dude!

dynamic

ex =

new

ExpandoObject
();

ex.Name =

"Casey"
;

ex.Greet =

new

Action
(() =>



Console
.WriteLine(
"Hello!"
));



Console
.WriteLine(
"Before:"
);

DumpProperties(ex);



ex.ThisIsAwesome =

true
;

Console
.WriteLine(
"
\
nAfter:"
);

DumpProperties(ex);

Console
.WriteLine(
"
\
nGreeting: "
);

ex.Greet();

Console
.ReadLine();

ExpandoObject


Okay, now that’s just insane.


System.Dynamic.DynamicObject


TryGetMember()


TrySetMember()


TryInvoke()


TryConvert()

Final Thought

PARALLELIZATION



Multicore Processors
Prevalent


Hard to write thread
-
safe


New Tools


Task Parallel Library

Let’s Multitask!

Old:


Action
<
int
> work = i => System.Threading.
Thread
.Sleep(i);


for

(
int

i = 0; i < 143; ++i)

{


work();

}

Task Parallel Library

New:

Action
<
int
> work = i => System.Threading.
Thread
.Sleep(i);


System.Threading.Tasks.
Parallel
.For(0, 143, work);


Yes, it’s that easy.

int
[] intArray = { 1, 3, 3, 4 };

Parallel
.ForEach<
int
>(intArray, i =>

{


Thread
.Sleep(i);

});


Or what about:

List
<
Action
> workObjects =
new

List
<
Action
>();

// Put lots of work into the workObjects list

Parallel
.Invoke(workObjects.ToArray());


For Each You Say?

Task

t =
Task
.Factory.StartNew(() =>

{


Thread
.Sleep(10);

});



Later on…


if

(!t.IsCompleted)

{


t.Wait();

}

// Task is complete; carry on




What about Fire and Forget?

Task
<
int
> t =
Task
<
int
>.Factory.StartNew(() =>


{


int

retVal = 0;


for

(
int

i = 0; i < 317; ++i)


{


++retVal;


}


return

retVal;


});


Later on…


if

(!t.IsCompleted)

{


t.Wait();

}


int

sum = t.Result;



But I want something in return!

SAMPLE


int
[] sleepTimes =
new

int
[] { 1, 2, 3, 4, 5 };



Sleep for x seconds


Run sequential then parallel


Sequential: Sum is 15


Parallel: ?

An Example

var

watch =
Stopwatch
.StartNew();

foreach

(
int

i
in

sleepTimes)

{


Thread
.Sleep(
TimeSpan
.FromSeconds(i));

}

watch.Stop();

Console
.WriteLine(


"oldSchool completed in {0} seconds."
,


watch.Elapsed.TotalSeconds);

});

Example: Sequential

var

watch =
Stopwatch
.StartNew();

Parallel
.ForEach<
int
>(sleepTimes, i =>

{


Thread
.Sleep(
TimeSpan
.FromSeconds(i));

});

watch.Stop();

Console
.WriteLine(


"New hotness completed in {0} seconds."
,


watch.Elapsed.TotalSeconds);

});

Example: Parallel

Example: Results

COVARIANCE AND CONTRAVARIANCE IN
GENERICS




Covariance

Narrow type → wider type

float


double


IEnumerable
<
out

T>


Dude, what’s that about that old Nintendo game?


Contravariance

Wide type → narrow type

double


float


IComparer
<
in

T>


Can be used with Generics:


Delegates


Collections


Interfaces


class

Foo

{

}


class

Bar

:
Foo

{

}


static

void

Dump(
IEnumerable
<
Foo
> objects)

{


foreach

(
Foo

o
in

objects)


{


Console
.WriteLine(o);


}

}


static

void

Main(
string
[] args)

{


List
<
Bar
> bars =
new

List
<
Bar
>(
new

Bar
[]


{


new

Bar
(),


new

Bar
(),


new

Bar
()


});


Dump(bars);

}

Covariance

Visual Studio 2008 / C# 3.5

Visual Studio 2010 / C# 4.0

class

Foo

{

}


class

Bar

:
Foo

{

}


static

void

Main(
string
[] args)

{


Action
<
Foo
> actionOnFoo = o => o.ToString();


Action
<
Bar
> actionOnBar = actionOnFoo;

}

Contravariance

Visual Studio 2008 / C# 3.5

Visual Studio 2010 / C# 4.0

QUICK HITS




Optional


C/C++ Style


Must follow all non
-
optional parameters


Named


Can specify parameters out of order

Optional & Named Parameters


static

void

Foo(
int

a = 1337,
int

b = 42)

{


Console
.WriteLine(a);


Console
.WriteLine(b);


Console
.WriteLine(
"
----------
"
);

}



static

void

Main(
string
[] args)

{


Foo();


Foo(317);


Foo(317, 831);

}

Optional Parameters

static

void

Foo(
int

a = 1337,
int

b = 42)

{


Console
.WriteLine(a);


Console
.WriteLine(b);


Console
.WriteLine(
"
----------
"
);

}


Foo(b: 317, a: 831);


Named Parameters


Don’t have to always use ref


Don't always have to pass objects


object

filename =
"file.txt"
;

doc.SaveAs(filename,
Missing
.Value,
Missing
.Value,
Missing
.Value,
Missing
.Value);


Becomes…


doc.SaveAs(
"file.txt"
);

Improved COM Interoperability

Other Treats


Enumerations'
HasFlag(enum)


string.IsNullOrWhiteSpace(string)


System.Lazy<T>


System.Tuple<>


System.Collections.SortedSet<T>


System.Guid.TryParse(string, out
Guid)

Cleaner ASP.NET Markup


Munged ID attributes:
ctl04_ctl03_blah


New options


AutoID


Predictable:
parent_child


Static

URL Routing a
-
la
-
MVC


/states.aspx?state=Virginia


/states/Virginia


System.Web.Routing.RouteTable


System.Web.Routing.RouteCollection.Add()

Other ASP.NET
Goodies


Page.MetaKeywords

&
Page.MetaDescription


Redirects


Response.Redirect

(302)


Response.RedirectPermanent

(301)


Extensible Caching


Memcached


AppFabric


web.config

transformations

Debugger Improvements

QUESTIONS?



Resources


Microsoft Brief:
http://code.msdn.microsoft.com/cs2010samples/Releas
e/ProjectReleases.aspx?ReleaseId=1686


Wikipedia:
http://en.wikipedia.org/wiki/C_Sharp_4.0


Scott Guthrie:
http://weblogs.asp.net/scottgu/archive/2009/08/25/vs
-
2010
-
and
-
net
-
4
-
series.aspx

cliss@ironworks.com

Twitter:
@caseyliss

http://underthehood.ironworks.com/