Archive

Archive for the ‘C# 3.0’ Category

Live Blogging RVNUG – December 2007

December 6, 2007 Comments off

Tonight I am visiting RVNUG (Roanoke Valley Dot Net Users Group) for the first time. Kathleen Dollard, a columnist for Visual Studio Magazine and author of Code Generation in Microsoft .NET (which I have and have read most of) is the featured presenter. She will be discussing “Refactoring with Generics”. How to make your code better with Generics, using Framework Generics, and how to use and make your own Generics.

Here are some bullets I garnered from the presentation:

  • Find out about the Converter<T> Generic Delegate.
  • “Team Test” is now part of VS2008.
  • Anonymous Delegates employ “Closure” – allows a private variable to be trucked off to (captured by) an out of scope method (like an anonymous delegate)
  • Return a LINQ list immediately by using “.ToList()”: no deferred execution
  • Format for declaring my own generics and specifying Type inheritance: public class GenericClass<TData, TCollection> : SomeBase where TCollection : List<TData> where TData : class

Conclusions

Overall, a good presentation. Unfortunately, it is a little dated when you consider all the new technologies out there. Kathleen did include some optional approaches using LINQ and Lambdas, but the bulk of the material is still 2.0 based. Don’t get me wrong: I’m not saying I didn’t learn anything because I did. I think I have a much better handle on creating my own generic classes now. But I think the target audience for this presentation should be developers moving from 1.1 to 2.0 or new developers.

Now for the scary part: the topic is very relevant. There are still an incredible number of people developing in pre-2.0 technologies who need this kind of information.

Kathleen is great: if you ever get a chance to go to a presentation of hers, by all means treat yourself: she really knows her stuff. We had a nice talk during dinner about the future of LINQ to SQL, OR/M, the Entity Data Model, and other Framework issues.? She was very patient with my questions and her answers reveal that she is one smart cookie.

Categories: .NET 3.5, C# 3.0

Upgrade your C# Skills part 3 – Lambda Expressions

December 5, 2007 28 comments

I’ve been very busy continuing my C# 3.0 and .NET 3.5 self-education. I’ve been focusing primarily on LINQ, but before I cover that here, which will take several postings, I wanted to cover Lambda Expressions. If you have been reading about LINQ and its related technologies at all, you’ve surely come across this term already. If you’ve already read some about Lambdas, then perhaps you came to the same conclusion I did: a lot of writers covering Lambda Expressions seem to want you to be boggled by them. In most articles, I found myself wading through a bunch of stuff I really did not need to know. In fact, it sometimes simply added more confusion.

So my goal in this article is to bypass all the pocket protector stuff and get right down to brass tacks. Here are a list of things I will NOT be covering that pervade almost every other article about Lambda Expressions:

  • Lambda calculus
  • Anonymous Methods
  • Functional Languages
  • Lexical Closures

If you are interested in any of the above, they are plenty of other articles out there. If, however, you are like me and just want to use this stuff, then read on…

Anonymous Methods

Before you scream foul, yes, I said I wasn’t going to discuss these, and really, I’m not. Or more accurately, I’m not going to explain them or show examples. You do have to know that Lambda Expressions are just another way to write Anonymous Methods. *whew*! Glad we got that out of the way!

The tricky part, though, for many programmers is knowing when to use Anonymous Methods. As far as our discussions go, it will be pretty easy: you want to use Anonymous Methods whenever you need to pass a method reference. This is done by use of delegates, something else I’m not really going to talk about.

So what you need to know is this: where ever you see a method that requires a delegate (or a reference to a method), you can use a Lambda Expression instead. An Anonymous Method is just a way to write the code for such a delegated method inline. So, we just need a way to know when we can use Lambda Expressions.

Actions, Predicates, and Funcs

What we need are Delegate Types. Delegate types are declared signatures for method calls that are used to wrap instance methods or, in our case, anonymous methods. Fortunately for us, there are some Generic Delegate Types built in to .NET that we can put to good use.

Action<T>

This is a Generic Delegate defined in .NET that will wrap and execute a method, passing it a variable of type T. Here is the MSDN Documentation. If you use this in a method declaration, you can actually pass a reference to a method, anonymous or otherwise, to a method of your own creation. For an example, check out this Extension Method:

public static void ExecuteOnValues<K, V>(this IDictionary<K, V> sequence, Action<V> action)
{
    if (sequence == null)
    {
        throw new ArgumentNullException("sequence");
    }

    foreach (var item in sequence.Values)
    {
        action(item);
    }
}

You can see here that our method signature expects a Generic Action<T> method reference. What we don’t know is what this method will do. The code line action(item) is saying “execute the method passed in on my action parameter, and pass it the item as a parameter.” So our Action method receives the Value of our Dictionary as a parameter and does something with it. We are going to use Lambda Expressions to define the “something”. Here is a simple example:

var dict = new Dictionary<int, string>();
dict.Add(1, "Coding");
dict.Add(2, "in");
dict.Add(3, "C#");
dict.Add(4, "Rules!");

dict.ExecuteOnValues(f => Console.WriteLine(f.ToString()));

Here we have created a new Dictionary<TKey, TValue> collection and added some data. Because Dictionary<TKey, TValue> inherits from IDictionary<TKey, TValue>, we can use our new Extension Method to execute some code against all the values in our Dictionary. But remember that our Extension Method really has no executing logic: it is expecting us to send it a reference or a delegate to it so it knows what to do. Enter the Lambda Expression. In the ExecuteOnValues method call above, f => Console.WriteLine(f.ToString()) is a Lambda Expression.

Anatomy of a Lambda Expression

// A simple Lambda expression
f => Console.WriteLine(f.ToString())

The “=>” thingy in the middle is the Lambda operator. This is what lets you know a Lambda is what is happening here. Let’s break the rest down into two parts: the left side and the right side. The left side represents a parameter list to be passed into the method. The right side represents the code the method will execute. Really, that’s it. You can make it harder if you want, but ultimately this is all it boils down to. Here is a diagram:

// A simple Lambda expression
f     =>    Console.WriteLine(f.ToString())
PARM Lambda CODE TO EXEUTE

So you can think of this as a method defined like so:

// A faux method representing a Lambda
void Method (unknownType f)
{
    Console.WriteLine(f.ToString());
}

In essence, without getting into all the pocket-protector details, this is what is the compiler is doing for you when it sees a Lambda Expression. The above is psuedo-code, and not entirely accurate, but you get the idea.

Where this gets confusing is that you really don’t see any type declarations, either for the parms or the return value. This is more Compiler Inference at work. In our example above, we specified that our Action generic was based on the Value Type of the Dictionary. The Compiler is able to look at the context of the Lambda Expression and simply infer that f is whatever type we specified on the Action parameter. You could write the details out, specifying the types, but not needing to is one of the major draws of Lambdas: the code is more compact and it “just works”. Now we’ll change our Dictionary to have a different Value type. We’ll make it our standard Person and add some people to it:

var dict2 = new Dictionary<int, Person>()
{
    {1, new Person() {FirstName = "John", LastName = "Smith", Age = 32, DOB = "12/31/1988"}},
    {2, new Person() {FirstName = "Jimmy", LastName = "Crackcorn", Age = 57, DOB = "08/08/1934"}},
    {3, new Person() {FirstName = "Mary", LastName = "Contrary", Age = 44, DOB = "09/10/2000"}}
};
dict2.ExecuteOnValues(f => Console.WriteLine("{0} is a {1} born on {2}", f, f.GetType().Name, f.DOB));

Now if we run this we’ll get these results (Click for full size image):

Person List
And now we get to see something else: in this Lambda, I am executing methods and Properties on my parameters. Pretty cool, huh?

So let’s read this Lambda out loud: “GIVEN f, EXECUTE {Console..WriteLine(“{0} is a {1} born on {2}”, f, f.GetType().Name, f.DOB));}”

Confused about the Looping? Don’t be: the loop is actually happening back in our Extension Method. All that’s happening here is that this code is executing (inside the loop) and using each Value from our Dictionary as the GIVEN parameter.

Predicate<T>

This is a Generic Delegate that evaluates a condition and returns true or false. Notice that Action<T> did not return any values. Predicate<T> is different because it returns a boolean value, and ultimately its only purpose is to determine whether or not a certain condition is met. Here is the MSDN documentation.

Let’s create a custom PersonCollection class and add a method that returns a sublist of Person objects who meet an unspecified criteria:

class PersonCollection : List<Person>
{
    public List<Person> MatchingPersons(Predicate<Person> condition)
    {
        List<Person> list = new List<Person>();

        foreach (Person p in this)
        {
            if (condition(p))
            {
                list.Add(p);
            }
        }

        return list;
    }
}

This code is specific to our PersonCollection class but still takes advantage of Predicate<T> to filter itself into a subsetted list. Let’s execute this now and get back just a list of Veterans:

var people = new PersonCollection()
    {new Person() {FirstName = "John", LastName = "Smith", Age = 32, DOB = "12/31/1988", IsMilitaryVeteran=true},
     new Person() {FirstName = "Jimmy", LastName = "Crackcorn", Age = 57, DOB = "08/08/1934", IsMilitaryVeteran=false},
     new Person() {FirstName = "Mary", LastName = "Contrary", Age = 44, DOB = "09/10/2000", IsMilitaryVeteran=true}};

Console.WriteLine("Print them all:");
people.ForEach<person>(f => Console.WriteLine("{0} is a {1} born on {2}", f, f.GetType().Name, f.DOB));
Console.WriteLine();

// Get a subset of people
var veterans = people.MatchingPersons(f => f.IsMilitaryVeteran);
Console.WriteLine("Print just veterans:");
veterans.ForEach<person>(f => Console.WriteLine("{0} is a {1} born on {2}", f, f.GetType().Name, f.DOB));

The beauty here is we did not specify what the criteria for the filtering was: we could have just as easily asked it for all the people whose first names begin with the letter “J”:

// Get another subset of FirstName beginning with "J"
var js = people.MatchingPersons(f => f.FirstName.StartsWith("J"));
Console.WriteLine("Print just Js:");
js.ForEach<person>(f => Console.WriteLine("{0} is a {1} born on {2}", f, f.GetType().Name, f.DOB));

Here is a screen shot of running all three of these in a row (Click for full size image):

Screenshot

Personally, I think this is a great tool, and the Lambda Expressions just make it that much more readable and easy to develop.

Func<T>

So far, we’ve seen Generic Delegates that return void and bool. That’s nice, and we can do a lot with them, but sometimes you need something more. This is where FUNC<T> comes in to play: it can return any type. In this case, the T is the return type. In the MSDN Documentation, they use “TResult” instead of “T”, so I’ll do that too. There are five Func Generic Delegates defined in .NET 3.5:

  • Func<TResult> – no parameters, returns type TResult
  • Func<T, TResult> – 1 parameter, returns type TResult
  • Func<T1, T2, TResult> – 2 parameters, returns type TResult
  • Func<T1, T2, T3, TResult> – 3 parameters, returns type TResult (are you noticing a pattern yet?)
  • Func<T1, T2, T3, T4, TResult> – 4 parameters, returns type TResult

What’s cool about Func is that you can create your own methods on the fly and give them meaningful names. Here is a simple example:

// Get a subset of people using Func
Func<Person, bool> isVeteranBeginsWithJ = f => f.IsMilitaryVeteran && f.FirstName.StartsWith("J");
Console.WriteLine("Print just veterans whose first name's begin with \"J\":");
foreach (Person p in people)
{
    if (isVeteranBeginsWithJ(p))
    {
        Console.WriteLine("{0} is a {1} born on {2}", p, p.GetType().Name, p.DOB);
    }
}

As you can see, I simply use my Func as any other method. I can see where this would come in very handy for short term reusability. Also, a lot of LINQ elements require Func delegates, so you have to have it in your toolkit.

Some odds and ends

There are a few items that I have to mention. First of all, Action<T> also has a few multiple parameter options:

  • Action<T1, T2>
  • Action<T1, T2, T3>
  • Action<T1, T2, T3, T4>

We did not discuss sending multiple parameters to a Lambda. To do so, wrap them in parentheses, like so:

// Example from Microsoft
(x, y) => x == y

While Compiler Inference is at work here, it is not required. If you wish to specify types for readability you can:

// Example from Microsoft
(int x, int y) => x == y

Calling a Lambda with no parameters, such as Func<TResult> is done with empty parentheses:

Func<string> getSomething = () => "Something";
Console.WriteLine(getSomething());

Lambdas can access local variables:

string todo = "To Do";
Func<string> getSomethingTodo = () => "Something " + todo;
Console.WriteLine(getSomethingTodo());

And Lambdas can be just as complex as you want them to be. Here is a Lambda that receives our custom PersonCollection and calculates the average age based on the DOB (if you’ve looked at the initializers, you’ll find that the Ages and the DOBs do not balance):

Func<PersonCollection, int> calculateAverageAge =
    (PersonCollection c) =>
    {   int totalAges = 0;
        foreach(var p in c)
        {
            string[] parts = p.DOB.Split(new char[] { '/' });
            int year = int.Parse(parts[2]);
            int calcAge = DateTime.Now.Year - year;
            totalAges += calcAge;
        }
        int averageAge = totalAges / people.Count;
        return averageAge;
    };

Console.WriteLine("Average Age of collection is {0}", calculateAverageAge(people));

And lots more. This is hardly the definitive article on Lambdas, but hopefully it explains enough to get you started. There is certainly enough background here to begin using Lambdas with LINQ, which will be next in this series of articles. Here is a link to the MSDN Lambda Expressions (C# Programming Guide).

Categories: .NET 3.5, C# 3.0

Making Automatic Properties Read Only

November 28, 2007 Comments off

In yesterday’s post, I included a blurb about Automatic Properties. Today, in my weekly C# class at my company, I was showing Automatic Properties to my students and I mentioned that you could not have a Read Only automatic property. To prove this, I removed the Setter from like so:

// This will not compile
public string FirstName { get; }

I then received a Compile error indicating that an Automatic Property must have both a getter and a setter. I was about to say that this proved my point when it dawned on me that I could try making the setter private, like so:

// Look, a Read Only Automatic Property!
public string FirstName { get; private set; }

Now this compiles just fine. I swear that at VSLive I saw someone try this and it failed, so either my memory is faulty or this was corrected before VS2008 went RTM. In either case, you can now implement an Automatic Property with a private Setter.

In my book, this is not truly Read Only, since the value can still be changed internally, but at least external consumers of the Property will not be able to alter its value, so I’ll still consider this a way to have a Read Only Automatic Property.

Categories: .NET 3.5, C# 3.0

Upgrade your C# Skills part 2 – Compiler Inference, Object Initializers, and Anonymous Types

November 27, 2007 7 comments

Well, that Title sure is a mouthful! “Compiler Inference”, “Object Initializers”, “Anonymous Types”: as fancy as these items sound, they are among some of the more mundane changes to C# 3.0. Don’t get me wrong: these changes lay the groundwork for all the really cool stuff going on in C#, especially LINQ. Truthfully, I should have covered these first, but I had actually been dreaming about Extension Methods, so I hope you’ll understand if I had to get that out of my system!

Compiler Inference

It probably isn’t fair for me to say this is “mundane”, but look at the two examples below:

// Old Way
Person p = new Person();
string name = p.LastName + " " + p.FirstName;

// New Way
var p = new Person();
var name = p.LastName + " " + p.FirstName;

Doesn’t seem like much, does it? All we did was replace the explicit Type with a new keyword called var. When you see var, what you are seeing is an instruction to the compiler to figure out for itself what Type the resulting variable will be. This is NOT var like in PHP or other loosely typed languages. Once assigned by the compiler, all the Strongly Typed rules still apply. And var can only be used for local variables, so it won’t be replacing all type references any time soon.

In the example above, “var p = new Person();”, the compiler will infer from the return type that variable “p” should be of type “Person”. Granted, in this simple example it doesn’t really mean much. It does mean less typing, especially when looping through generic collections, but where it will really come into play is with Anonymous Types and LINQ. In fact, without Compiler Inference, Anonymous Types could not function, but more on that later in the article.

There is some debate going on as to when to use Compiler Inference. Some feel that using var whenever possible is just lazy and leads to less readable code. These people think that you should use it only when it is really needed. In other words, if I know p is going to be a Person, then why not say so explicitly? Personally, I don’t have an opinion. I’ll use it when it seems convenient and of course where it is required. It certainly makes looping through Collections nicer to write:

// assume people is a List<Person>
foreach (var person in people)
{
    Console.WriteLine("{0} {1} is {2} years old.", person.FirstName, person.LastName, person.Age);
}

I have to think that if Person is later subclassed, fewer changes would be required to make this code continue to function. Is it lazy? Perhaps, but we all know that a good programmer is a lazy thief!

Object Initializers

Another cool feature are Object Initializers. Initializers allow you to set a series of Property variables when you create the object. How many times have you coded something like this:

Person p = new Person();
p.FirstName = "John";
p.LastName = "Smith";
p.Age = 32;

Now, you can shorten this considerably. Sort of like Array Initializers, which I’m sure we’ve all used, the syntax is a list of property=value pairs inside curly braces immediately following a constructor:

// You could, of course, use var here...
Person p = new Person() {FirstName = "John", LastName = "Smith", Age = 32};

An interesting side note about IntelliSense: naturally, inside the initializer block, IntelliSense will show you the list of properties available for the Person object. As you use Properties in the Initializer block, you will notice that they disappear from IntelliSense. This is a quick way to make sure you set every property (if you need to), and should help prevent listing duplicate properties (which, incidentally, throws a compiler error).

Now, for some extra coolness, you can embed Object Initialization inside a Collection’s Object Initializing block, so that this:

List<person> people = new List<person>();
Person p = new Person();
p.FirstName = "John";
p.LastName = "Smith";
p.Age = 32;
people.Add(p);

Person p2 = new Person()
p2.FirstName = "Jimmy";
p2.LastName = "Crackcorn";
p2.Age = 57;
people.Add(p2);

Person p3 = new Person();
p3.FirstName = "Mary";
p3.LastName = "Contrary";
p3.Age = 44;
people.Add(p3);

Can now be done like this:

var people = new List<person>()
    {new Person() {FirstName = "John", LastName = "Smith", Age = 32},
     new Person() {FirstName = "Jimmy", LastName = "Crackcorn", Age = 57},
     new Person() {FirstName = "Mary", LastName = "Contrary", Age = 44}};

As you can see, this is very concise and readable code. Less Typing = More Cool!

Automatic Properties

Since we are talking about properties, at least in a round about way, I want to throw in a quick item you may not be aware of called Automatic Properties. We all know that we are supposed to be exposing access to our variables via properties, but a lot of the time all we want to do is to be able to read and write the variable data. As such, we end up with a lot of code that looks like this:

private string _firstName;
public string FirstName
{
    get { return _firstName; }
    set { _firstName = value; }
}

Now, there is nothing wrong with this approach, but it feels a little verbose. To address this, you can now use an Automatic Property:

public string FirstName { get; set; }

The two main differences are that you do not define the variable, and you do not have to write the getter and setter logic. In fact, you’ll notice there aren’t even curly braces for get or set. The upside is that it is again less code for a common function. The downside is that you do not have an internal variable to access: you must use the Property name, even internally. Also, the Property must contain both the get and the set, so you cannot have a read-only Automatic Property. You also cannot add custom logic: get and set default behaviors are it.

The plus, though, is that if you start with an Automatic Property and need to add any of this functionality, you simply create the variable and update the Property as you would have before. There is nothing magic about Automatic Properties, this is just another example of the Compiler doing menial work for you. One last tidbit: in VS2008, if you use the “prop” code snippet, you will get the format of an Automatic Property by default. It really replaces the need for my Property Builder tool.

Anonymous Types

When I first learned about Anonymous Types, I didn’t think it would be all that big of a deal. The more I think about it though, the more I can see a use for it. And when I saw how they are used with LINQ, I was sold. Basically, you can define a Type without naming it or creating a separate class definition. Let’s revisit our Person and People class from before, only this time I am not going to define the Person Class:

var p1 = new {FirstName = "John", LastName = "Smith", Age = 32, FirstName="Harold"};
var p2 = new {FirstName = "Jimmy", LastName = "Crackcorn", Age = 57};
var p3 = new {FirstName = "Mary", LastName = "Contrary", Age = 44};

Here I have created three instances of my new Type, but I have not explicitly defined the type definition. Instead, the compiler has created a class for me and given it the Properties I listed (using our new friend, Compiler Inference). All of the properties are read-only, so once created, the values cannot be changed. Since the three objects above are all identical in their property names, all three objects are of the same (unknown) type. And IntelliSense still works as well: Typing “p1.” will reveal a list of the properties. I said earlier in the article that Anonymous Types could not function without Compiler Inference: hopefully it is obvious now what is happening above. “var” is the only option here, because the Type of the variable does not exist at design time. The Compiler must infer the Type to be of whatever class the Compiler creates, otherwise, you could not have Anonymous Types in a language like C# because of its strong typing.

Of course, there is a catch: as of yet, I have not figured out a way to use these in a list. You cannot use a Generic list, because there is no Type for strong typing. You can store them as Objects, but then you cannot cast them back out because there is no type. So what does this particular method buy you? In my opinion, not much. There could be an argument for using this method to replace the use of temporary Structs, a method I use frequently to store grouped information. But since I can’t store them in a list or pass these objects around, it would be a very limited approach.

There is, however, a necessary use for Anonymous Types: LINQ requires them to be able to create custom query results as a Collection. We’ll explore that more later this week, so be sure to check back.

Categories: .NET 3.5, C# 3.0, Visual Studio

Upgrade your C# Skills part 1 – Extension Methods

November 26, 2007 9 comments

DOWNLOAD the Code!

Now that I have VS2008 and .NET 3.5 installed, I am going to begin a series of articles on some of the new features you can use in C#. My hope is to add one new article a day for the rest of this week. Along the way, we’ll explore some of the new language features for C# 3.0. Truthfully, they aren’t all that new since C# 3.0 has been around for about a year, but support for them is now built in to Visual Studio, so using them is now realistic. Also, with the release of VS208, I’m sure this will be the first time most developers will be exposed to them. I’m going to start by introducing one of my favorite enhancements: Extension Methods.

Extension Methods

Extension methods offer us a way to expand class functionality even if we do not have access to the code for those classes (including sealed classes). In other words, we can add our own functionality to any object type. Have you ever looked at the String class and said “why can’t I do {fill in the blank} with a String?” If so, you probably created your own method, passed it the string in question, and consumed the return value:

string s = "1234";
string z = Reverse(s);

If you’ve ever written code like this, then Extension Methods are for you. In the case above, it should be obvious that Reverse is a static method, since it is not attached to an instance. Wouldn’t it be nice instead to write this?

string s = "1234";
string z = s.Reverse();

I know it is a subtle difference, and in this case not a terribly functional one, but hopefully you can see the difference. Instead of passing the string variable to a static method, you can treat your methods as though they belong to the string class. And these new methods are available in Intellisense: when I type “s.”, I will see my extension methods right alongside all the native methods, which makes finding and using them much more palatable. And you will find in the new Intellisense that Microsoft itself is making heavy use of Extension Methods. You can tell in two ways: first, the icon for extension methods is the familiar purple box but accented with a blue down arrow. Secondly, when the method description pops up in Intellisense, the description is preceded by “(extension)”.

Let’s look at a more reasonable example. Using the Regex class, you can determine whether or not string matches a Regular Expression pattern by passing a string and a pattern to the Regex.IsMatch() method:

string s = "This is awesome";
if (Regex.IsMatch(s, "awe"))
{
    Console.WriteLine("Yep, this is a match!");
}
else
{
    Console.WriteLine("Sorry, no match.");
}

I think it would be handy on occasion to simply “ask” the string itself if it matches a certain pattern:

string s = "This is awesome";
if (s.IsRegexMatch("awe"))
{
    Console.WriteLine("Yep, this is a match!");
}
else
{
    Console.WriteLine("Sorry, no match.");
}

Pretty neat, huh? OK, I admit it doesn’t appear to lessen your code, but to me it can make your code make more syntactic sense. And given a more complex example, it could do a lot for you. Richard Hale Shaw showed us an example of a .ForEach extension for IEnumerable<T> collections that would knock your socks off! Imagine being able to loop through an entire Collection and perform some action on each item in a single line of code, without passing the Collection off to a method? It would look something like this:

DirectoryInfo dir = new DirectoryInfo("C:\\");
FileInfo[] files = dir.GetFiles();
files.ForEach<fileinfo>(f => Console.WriteLine("{0} {1}", f.FullName, f.Length));

For now, ignore the code between the () – that’s a Lambda Expression, and we’ll get to those later in the week. Just understand that with this sample above, each FileInfo object in the array will have the passed Action applied to it. How many foreach loops do you think this little nugget could eliminate?

Now, I hope this will get you interested in Extension methods: it didn’t take me too long to think these are very cool! To get you started, I’m adding a new project called DevelopingForDotNet.Extensions to the Free Code page . My take on Richard’s method(s) are included, along with a handful of String and Numeric operations. Nothing too fancy, but hopefully enough to help get you started.

Enough already, how do I do it?

Creating Extension Methods is very simple. First, you must follow these simple rules:

  1. Extension Methods must be static, defined in a static class
  2. Extension Methods must be public
  3. The this keyword precedes the first parameter

We’ll take these one at a time. First, the method must be static because of how the compiler handles extensions. Behind the scenes, whenever an Extension Method is employed, the compiler actually generates code to call the static method. The idea of the Extension Method is just a visual layer for the developer: behind the scenes the actual static method is being called. Also, these methods can be called in a static fashion, rather than as methods attached to an instance. Which brings up another good point: the class name the Extension Methods are in is essentially irrelevant (unless you are going to call them explicitly). I put all my extensions in a single static class (imaginatively called “ExtensionMethods”).

Second, they probably do not absolutely have to be public, but if they aren’t then you are severely limiting the functional scope, so what’s the point?

Finally, preceding the first parameter with “this” is what tells the compiler that this is an Extension Method. It is also probably going to be the main source of initial confusion, because you do not pass this parameter (unless you are calling the method explicitly).

Overall, these are fairly simple rules to follow. Here is a handy method I’ve used for a while:

public static string RightAdjust(string s, int Size, char FillCharacter)
{
    string ch = FillCharacter.ToString();

    if (s.Length > Size)
    {
        throw new ArgumentException("Size of Value larger than Requested Size.");
    }

    while (s.Length < Size)
    {
        s = ch + s;
    }

    return s;
}

This method receives a string and right adjusts it to the given size, filling the leading characters in with the passed char. Calling it looks like this:

string s = "1234";
s = RightAdjust(s, 7, '0');
// Value of s is now "0001234"

Now, let’s convert this to an Extended Method:

public static string RightAdjust(this string s, int Size, char FillCharacter)
{
    string ch = FillCharacter.ToString();

    if (s.Length > Size)
    {
        throw new ArgumentException("Size of Value larger than Requested Size.");
    }

    while (s.Length < Size)
    {
        s = ch + s;
    }

    return s;
}

All we did was add “this” before the first parameter. Now we can call it like so:

string s = "1234";
s = s.RightAdjust(7, '0');
// Value of s is now "0001234"

Naturally, you will need to add a reference to the DLL that contains your Extension Methods in order to find and use them.

Overloading Extension Methods:

Just like other methods, Extension Methods can be easily overloaded. My approach for overloading has always been to put all the functionality in the method that requires the most parameters. I then simply have my overloading method signatures call the primary method, sending it the appropriate parameter values. Looking at the RightAdjust method above, I want to establish a method that will use a blank character as the default fill character if one is not supplied. What’s different about overloading extension methods, is that I actually employ the primary extension method in my overloading methods:

public static string RightAdjust(this string s, int Size)
{
    return s.RightAdjust(Size, ' ');
}

So now I can call this method passing it just the Size parameter, and that method then calls the primary method using the Extension Method mechanism.

Conclusion:

Extension Methods can be as simple or complex as you like. They are a nice syntactical enhancement to the language that lets you enhance other objects and use them how you would like. But beware: you could easily go overboard. I mean, there is no reason to create a MakeDirectory method for a TimeStamp instance, but you could. Just use common sense and make sure that the extensions you create apply to the object type and way that you would use them.

Post Conference Detox

November 16, 2007 Comments off

I am travelling home today, but in between flights I am checking into a few items. First of all, and yes I know most of you are saying “Duh!”, I am checking out MSDN Subscriptions for the first time. See, when we started learning .NET we did not know if it would stick for us not, so the idea of committing to a subscription just wasn’t in the cards. Now, two versions of VS later I think there is no question that we are in .NET to stay.

I’m still waiting for VS2008 to RTM before I download it, but this way I can do it without waiting for CDs or anything like that (not to mention all the other code I get access to). The Visual Studio Professional version of MSDN is $1199 with an annual renewal of $799. Again, a no brainer.

I’m also looking at Microsoft Expression Blend. Preview 2 is out, and supposedly when it goes RTM it will be available on MSDN as well. I think I will go ahead and download the free tria now that XAML makes a lot more sense to me.

So, I have begun detoxing and will be employing these new goodies as soon as possible.? There are a million things floating about in my head.? I actually fell asleep last night thinking of a new WPF layout for a small internal database I started last week. I haven’t been this excited about coding in a long time: thank you Microsoft!

Categories: .NET 3.5, C# 3.0, WPF

Live Blogging VSLive! Austin – Day 4

November 15, 2007 Comments off

9:00am:

Just about to start a Post-Conference workshop entitled “Advanced C#: Moving up to LINQ, VS2008, and .NET 3.5” by Richard Hale Shaw. Richard is extremely knowledgeable and has a tendency to go into deeper detail than anyone else, so this should prove to be a challenging class. Watch for updates throughout the day.

10:50am update:

Wow! I can’t wait to get my hands on VS2008 and .NET 3.5! Lots of stuff going on: we’ve been covering Custom Iterators again, which is pretty cool in its own right but has been around since 2.0. We’ve been covering them, though, in the context of Extension Methods which are HOT. Keep watching this site, you’ll see lots of stuff coming up in the future about Extension Methods.

I do have a couple quick bullets that came up:

  • DataContext is the key object type in LINQ
  • DataContext has a .Log method that will reveal the actual SQL that was executed
  • LINQ for SQL only works against SqlServer 2000+ : more evidence that we need to switch to SqlServer
  • Compiler Inference is very cool and reduces a lot of code. For instance: var allows the Compiler to infer the variable type from the return object and Anonymous Methods can be replaced with Lambda Expressions.
  • var will only work for local variables

1:30pm update:

Lambda Expressions are something else I’ll be exploring and posting about in the near future. Essentially, a Lambda Expression is a syntax method of creating Action<T> and Predicate<T> objects (there is another but I don’t recall its name). These objects are used by LINQ and some other constructs. Without Lambda expressions, these could be created using anonymous methods or by outsourcing the method call signature. Trust me, for most applications Lambda Expressions will be much better. There is too much about them to show how they work here, so here are a few bullets with the caveat that if you have not seen Lambda Expressions they won’t mean much for you:

  • Lambda Expressions can consume outer variables
  • Lambda Expressions can contain embedded code
  • Lambda Expressions can be used in LINQ or anywhere else that the return types are needed
  • Very readable, once you understand the syntax
  • Scope for Lambda variables is protected
  • Here is a sample line using a Lambda: .Filter( f => f.Length > fileSize )
  • In this case, “f” is a variable that lives only inside the (). “=>” is the Lambda Execution operator. “fileSize” is an outer variable (defined and populated elsewhere in the scope)

Other goodies:

  • Custom Iterators, and as such LINQ query objects, employ “Deferred Execution”. In other words, the actual IEnumerable<T> return value is not populated until the object is used (as opposed to when it is defined)
  • Extension Methods can be used in LINQ alongside the system defined actions
  • In VS2008, you can step through .NET Framework code in DEBUG (I believe there is an additional install to make this work)
  • LINQ can create Anonymous Types: in other words, the resulting IEnumerable<T> of a LINQ statement can be of a Type and structure that is not a defined type. This is very cool!
  • Properties in Anonymous Types can be based on Method call results
  • Properties in Anonymous Types can be named as desired
  • Properties in Anonymous Types can be other Complex Types

3:20pm update:

Lots and lots of details, and my seat is getting really sore, but I am here until the bitter end! Here are a few highlights from the last section:

  • LINQ sequences (Richard’s name for the resulting IEnumerable<T> collections) can be combined using .Concat() as long as the resulting Types are the same
  • This is even true for Anonymous Types: as long as they are defined exactly the same
  • LINQ can group results: this ends up in a IGroupedEnumerable that holds a set of Key Value pairs of the group key and IEnumerable<T>
  • The LINQ group feature can be based on an anonymous type (defined as part of the group statement)
  • Not LINQ related, but Richard mentioned something about using Partial classes as a way to protect custom code from Code Regeneration – great idea that also solves a problem I’ve had in my own CodeGen of ensuring that variables were defined as protected instead of private (since my system inherits from the generated abstract class) Update: I spoke with Richard after the workshop about employing this as a thin abstraction layer for DAL objects (Data Access Layer) and he suggested this would not be a good approach for that application.? And I may have misunderstood what he was saying in the first place, but I do think it led me to the idea that Partial classes could be a solution to this problem.

4:45pm update:

The last section was mostly about XLINQ (LINQ to XML), and we have plenty more to cover. The new XML classes are very easy to use and intuitive:

  • Essentially an OO wrapper around XML
  • XElement is the key class and represents an XML element
  • XElement has an “Elements” Collection of child XElement objects which is an IEnumerable<XElement>
  • This means that we should be able to use LINQ over the Elements collection

5:40pm update:

Down the home stretch. These are definitely long days, but well worth every minute.

I want to clarify something from above: the classes I mention for XML are XLINQ. These classes are found in System.Xml.Linq. After the XML is read in to these objects, then LINQ to Objects can be used as before. So XLINQ is LINQ, it just doesn’t look like the other flavors of LINQ.

Also, Richard showed a nice method of creating and storing much cleaner XML code based on defined classes behind the scenes. Then the Read and Write methods are abstracted out using Extension Methods and Generics. Very clean and powerful, and overall a fairly straight forward and simple approach.

Conclusions:

Well, this is the end of a great week. If you ever get a chance to attend one of these events, by all means you owe it to yourself to go. Here are the technologies I will be exploring in great detail as soon as I get back to the world:

  • LINQ – this is the KING of all the new MS technologies
  • WPF – simply awesome: a new paradigm in GUI design with great promise
  • SilverLight – a whole new web experience, both for developers and consumers
  • IIS 7.0 – looks substantially easier and more functional
  • Entity Data Model – not ready yet but will be soon and another paradigm shift
  • Visual Studio 2008 – should be RTMing this month. If you want to do any of the above, you’ve got to have the right tools.

I’m sure there’s more, but I am brain fried and butt dead. Check back often, I expect lots of new posts in the near future as I work through all this stuff.

Live Blogging VSLive! Austin – Day 3

November 14, 2007 Comments off

10:10am – Keynote:

The keynote this morning was “Take on your toughest challenges with Visual Studio 2008” by Sam Gavitt of Microsoft. The presentation was a practically oriented tour of Visual Studio 2008 ad its new features and capabilities. Some stuff we’ve already heard and seen, but this presentation was very solid. As usual, here are some highlight bullets:

  • VS is focused on three areas: User Experience, Collaboration, and Productivity.
  • Should be shipping via MSDN any day now – not to self: subscribe to MSDN!

Sam’s “Top Ten Reasons to Switch to Visual Studio 2008″ (with apologies to David Letterman):

  • WPF Integration and Interoperability
  • C# and VB language improvements
  • New HTML Designer
  • JavaScript Debugging
  • WCF/WF Integration
  • AJAX Integration
  • Unit Testing
  • Integrated Office Development
  • LINQ
  • Multi-Platform Targeting

These are definitely cool features, but I disagree on the last one. Multi-platform targeting (the ability to target code for any version of 2.0, 30, or 3.5) is a great feature, but it is not a reason to switch to VS: it the solution to a reason not to switch. LINQ is absolutely king: the absolutely best new language feature I’ve ever seen, period. Along with WPF and the promise of the Entity Data Model, LINQ represents a shift to Declarative programming. It will improve code readability, increase productivity, and result in significantly less code. If you really want to (and are stubborn) you can use LINQ in VS2005, but you get no real help from VS for using it. Switch to VS2008 and you get cool stuff like Intellisense and LINQ object creation. LINQ alone is worth the price of admission.

Web Application Stuff:

  • CSS Editing is greatly enhanced
  • CSS now has Intellisense
  • CSS Intellisense is also available in ASP.NET code
  • Tons of new file templates
  • JavaScript syntax highlighting
  • JavaScript Intellisense
  • JavaScript debugging
  • AJAX is SUPER easy in VS2008 – the demo blew me away

Windows Application Stuff:

Most of the stuff he talked about I’ve already posted a bunch on, namely WPF, VS, and Blend Coolness (but remember that Blend is not part of VS). He did briefly touch on WCF and WF integration, which I think is going to be valuable.

Office Integration Stuff:

OK, this is very very cool: Office development tools are now part of VS. You can add toolstrip buttons and features in Office products from your application. You can generate Office docs from your app. You can even create and embed your own Forms, including WPF stuff, in other Office apps. This sort of extension capabilities used to be a specialty in its own right and required specific training and tools: now anyone can do it, and it is slick.

11:37am update:

Just attended a session entitled “C#3.0 and LINQ Under-the-Hood” by Richard Hale Shaw. Richard has such a depth of knowledge that he is sometimes hard to follow, just because of the sheer amount of information he is capable of imparting. Truthfully, he didn’t talk much about LINQ at all, but rather he really got into the nitty gritty of the C# components that go into making LINQ possible.

Extension Methods:

A great technology that is going to be very useful, primarily for readability and productivity.

  • Add helper methods to classes you can’t extend
  • Operate on variables as thought he methods belonged to the actual class
  • The class name of the defining class is irrelevant, but it must be static and must be within appropriate scope
  • Extension methods must be defined as static
  • Obviously, a reference to the Extension method dll must be included in the consuming code
  • Intellisense indicates whether or not a method is an extension by prefacing it with (Extension)

Custom Iterators:

  • Lie at the heart of LINQ
  • Can be created by any method that returns IEnumerable, IEnumerable<T>, IEnumerator, or IEnumerator<T>
  • IEnumerator and IEnumerator<T> are preferred because IEnumerable is reserved for the primary Iterator of any given Collection
  • LINQ uses Deferred Execution based on Custom Iterators
  • Query does not hold data, but rather the mechanism for acquiring the data
  • Sequence methods (emplyed by LINQ) are built on Custom Iterators

Generic Delegates, Anonymous Methods, and Lambda Expressions:

  • Generic Delegates allow you to abstract and postpone the Action delegates until runtime
  • Anonymous delegates (a 2.0 technology) allow you to create and return methods on the fly: the compiler then generates the necessary code
  • Lambda expressions map to Generic Delegates to execute Anonymous Delegates in a more coder-friendly manner

12:45pm update:

“Using Visual Studio and the Expression Suite to Build Great User Experiences” by Denny Boynton.

A little bit of a misnomer: we really didn’t use Expression Studio, just Blend, but he did show something that was built using Expression video manipulation software (the name escapes me). He also did everything in a SilverLight application, which was good because it was the first one we’ve seen implemented in SilverLight.

I don’t have a lot of notes, basically we got to watch him work and start to get a feel for how the tools might be used in development. He never once edited XAML and only showed it to prove that you could get to it. He really segregated the Design work from the Development work, and the vision is starting to gel: this could really work. One of the other attendees pointed out that with these tools, you realistically could have separate designers. Maybe Microsoft is ahead of the game, predicting how it’s going to be rather than reacting to how it really is.

  • We really need a Rich User Experience (UX)
  • SilverLight is based on the RIA model (Rich Internet Application)
  • A lightweight plug in for IE, Firefox, Safari, and Opera (almost)
  • Runs on Windows, Mac OS X, and Linux (through “moonlight”)
  • Blend is really moving into the Designer Space
  • Designers are only limited by their imaginations: developers have always been limited by implementation capabilities
  • With XAML, those limitations are removed by completely separating the UI definition from the Code behind it
  • Expression Studio includes tools for Web design, Interactive design, Graphics Design, and Asset Management

3:10pm update:

Attended “IIS 7.0 for Web Developers” by Robert Boedigheimer. I need to preface all this with the statement that I am not an IIS person. I have limited experience with it, a few minor configs here and there on IIS 5.0 and 6.0, but nothing serious or production in nature. All that being said, based on the presentation and the reactions of those around me, IIS 7.0 is a great improvement over previous versions.

  • Broken up into a modular architecture
  • Uses pluggable components
  • Reduces attack surface and memory footprint
  • Configuration is all in XML
  • Installed modules are chosen in the configuration, so can be easily turned on and off without restarting IIS
  • Can be controlled from site to site (I think)
  • Modules are similar to ISAPI Extensions
  • Handlers are similar to ISAPI Filters
  • Custom Dialogs can be integrated into IIS Manager
  • Custom configurations are permissible
  • Configuration is independent for each website
  • You can write and apply .NET code to alter/extend IIS
  • Any request can fire .NET code (that you can develop!)
  • Modules are safer than filters because they are managed code BUT you still have to be wary of a performance impact (based on what you are asking the requests to do)
  • Header Details can be removed before a Response is sent – good for removing Server Identification information

.NET Integration:

It definitely appears that one of the big enhancements is the integration of custom .NET code. I can definitely see the power in being able to write my own methods to “do stuff” at any step in the process. Runs in one of two app pools: “Integrated” means that the .NET is in the Pipeline which “Classic” executes as ISAPI.

Forms Authentication:

In IIS 6.0, only ASP.NET files are protected. In IIS 7.0 all files can be protected using ASP.NET 2.0 Membership Providers for security. The authenticated user ID has been added to the log files. This non-ASP.NET file inclusion is disabled by default and must be enabled in the web.config file.

IIS Management:

  • appcmd.exe – Command line control
  • IIS Manager provides a GUI method
  • WMI Scripting is available
  • Can be done in custom .NET code by emplying the System.Web.Administration namespace

Built in Diagnostic Tools:

  • Traps and stores errors
  • Logs everything that happens
  • Failed requests are stored in an XML file
  • Can be configured to store all requests (or specific ones)

Run-time Status and Control:

You now have access to Internal Status information such as pools, processes, requests, etc. Accessible via all the above mentioned Management methods.

4:20pm update:

Just sat through a class on ASP.NET Architure by Paul Sheriff. A good overview of smart ideas for ASP developers. Not really an architecture, but lots of good common sense suggestions. Basically they boil down to these few suggestions:

  • Use CSS, Skins, Themes, and MasterPages
  • Wrap MS code that can cause you problems such as Sessions, Cache, Exceptions, ConfigurationManager, etc.
  • Create your own Base Page class and inherit all your pages from that base

CSS, Skins, Themes, and MasterPages:

  • CSS allows good separation of presentation and information
  • CSS promotes good structure (my note: this includes adding Syntactical value)
  • CSS is very flexible and is a well published web standard
  • CSS is cached on the client side and usually should be included as external files
  • SKins are like server-side CSS for ASP.NET controls
  • Themes group Skins and CSS together
  • Sites can have multiple skins and themes
  • Skins can be either Global (default) or Named (ID based)
  • Skins can be applied at runtime via the PreInit event
  • Themes are not set at runtime and cannot be established at the MasterPage level
  • There can be more than one MasterPage, but only one specified per page
  • MasterPages allow a consistent look and feel across an application
  • MasterPages can contain code
  • Subsequent pages use the Content are to deliver their information

Wrapping ASP.NET Constructs:

Wrappers are a powerful tool in many coding scenarios. In ASP.NET, wrapping such things as the Session variable array has many benefits:

  • Insulates code form future MicroSoft “enhancements”
  • Places code management in a single location
  • Allows variable initialization and implements default behaviors
  • Use this approach to wrap Exception management, Caching, ConfigurationManager, etc.

The last bit of advice is great: create a BasePage class that inherits from System.Web.UI.Page. Then have all of your Pages inherit from that class. This gives you global control over behaviors, can be used to implement security, provides consistency, etc. This is a rgeat idea and easy to implement, even after the fact.

The Last Session:

I went to a session on Distributed Data Application Design and Architecture, but I have to tell you I was pretty brain fried by then. The content was a little over my head, the presenter was very fast, and I really struggled to follow along, let along take notes for you guys. It’s probably for the best anyway as I doubt I would have made much sense.

See you tomorrow for the last day, I’m going to get some rest. And have some Tex-Mex food: benefits of visiting Texas!

Live Blogging VSLive! Austin – Day 2

November 13, 2007 Comments off

Keynote Address “Mapping your way through Microsoft’s Managed Data Access” – Michael Pizzo, Microsoft

10:30am:

The purpose of LINQ is to overcome some of the inherent flaws in Ad Hoc SQL data access from applications.

  • LINQ provides a set of language extensions
  • Integrates Query access as part of the application rather than implemented as Strings
  • Return values are in fact classes complete with strong typing rather than generic DataSets
  • Implements IQueryable to use LINQ over Collections
  • LINQ is available against DataSets, XML, and Entities as well as SQL

LINQ to SQL:

This is going to be the most important part of LINQ. This will essentially allow integration of the SQL Schema into usable objects in the Application.

  • Essentially a Strongly Typed SqlClient
  • Classes map to tables, views, SQL, and other Schema
  • Classes are generated by the LINQ Designer in VS2008 (saw a great demo of this)
  • Allows simple renaming of properties
  • Foreign Keys are implemented as Relationships
  • This means that additional table rows can be read in using Object syntax as opposed to additional SQL
  • Allows Type Inheritance for sub-Schema relationships
  • Can perform better than IDataReader
  • Can use StoredProcedures instead of SQL
  • Uses DataContext objects instead of IDbConnection – be sure to wrap in using statements for proper disposal
  • SQL Results become objects
  • Foreign Keys are available as Collections
  • DataContext has a .Log property for retrieving connection information
  • DataLoadOptions class allows finer control over when and how Related tables are read into the object

LINQ to DataSet:

  • DataSets still have value
  • Disconnected, serializable, etc.
  • LINQ makes filters, joins, projections, cross DataTable and cross Collection queries
  • Supports Typed and Untyped DataSets

ADO.NET Entity Framework:

The Entity Framework allows the Database Schema to be translated into complex Business objects.

  • Object Models are more complex than Schema’s rectangular storage model
  • Enables apps to work with higher level concepts such as relational navigation
  • Supports Type inheritance
  • Built over DataProviders
  • EntityClient is a declarative mapping of model to schema
  • LINQ can run over EntityClient
  • Produces Business objects
  • Provides Change tracking
  • Designers for this built into VS2008

The Future – Astoria:

  • Data Services over the web
  • LINQ/Query/CRUD over the web
  • Delivered as XML
  • Consumed over HTTP
  • LINQ can be used in Silverlight

11:40am update:

Attended “LING: What’s it all about?” by Ken Getz. I was really afraid that after the excellent keynote it would be repetitive, but NOT SO! I got so much out of it, and lots of it is not LINQ specific.

  • LINQ format is From… Where… OrderBy… Select
  • Select is always last, which really throws us SQL users
  • Select is last in order to properly support Intellisense (which unfortunately really only works in VB for now)
  • The From clause includes an item handle and indicates a Data Source
  • Uses implicit variable declarations – in both VB and C#, you can get an object variable to define it’s own type based on return value

Extensions Methods:

  • Add new methods to existing classes without access to the source code
  • Must be Public
  • Must accept a parameter of the type you wish to extend
  • In C#, it must be defined in a Static Class
  • C# uses the this keyword to indicate that this is an extension method
  • Can be used as a Static Class Method or an Instance method

Automatic Properties:

  • For properties that only expose an internal variable, the need to define and use that variable is no longer required
  • Does not require Constructors to update them, but it opens the problem of initializing properties that are not included in any constructor
  • SO – a Constructor can be used that does not actually exist: properties can be indicated on the new statement like so: MyClass c = new MyClass() {prop1 = value, prop2 = value};
  • Which means you can use a Constructor that essentially does not exist

LINQ for Objects:

  • Great for analyzing Collections
  • Takes advantage of Extensions Methods
  • Query class has many built in extensions:Any, All, Average, Where, Concat, Contains, Convert, Count, Distinct, Except, etc. etc.
  • Can use functions in Select clause
  • Functions must supply an expression (called “Lambda Expressions”)
  • Can include Anonymous Methods
  • Expressions can only have one item in and one item out
  • There can only be one expression on a function
  • Example: foreach(Actor a in Actors.Where(x => x.BirthDate.Month == 9))
  • “x” above is the individual object notation, “=>” indicates execute this comparison
  • Can use Anonymous Types – essentially, these are objects created on the fly (like creating columns in SQL Select) and added as a new Type to the resulting objects in the resulting Collection
  • Example: “Select new {NameOfProperty = actor.LastName + “, ” + actor.FirstName}”
  • Use Skip and Take to paginate different rows from within a collection

1:40pm update:

Attended “Styles and Data Templates” given by Bill Hollis. A good follow on from where we left off yesterday, the class got into some of the finer aspects of Templates and Styles. The more I see this stuff, the more I want to smack my head: I’ve had 3.0 installed since last year’s conference, but I’ve never forced myself to spend some time learning any of it. I look at it now and wish I had. But in truth this is the right time to be learning about it: with VS2008 and Blend, the technology is finally beginning to catch up with the theory. This is also the right time for my company given that we are just entering the development stage of a new suite of Applications. But enough rambling, on to the highlights:

  • Styles can be changed on the fly for any Element using the FindResource() method
  • TargetType is used to specify a style for all Elements of the same type en masse (within subsequent scope). This can be applied at any level, where ever a Resource can be defined (which is anywhere)
  • TargetType can only be applied to a single Type (this is not true for named Styles) – it cannot be found and applied to children of a different type
  • You can develop and import ResourceDictionaries to store Resources externally – think reuse, like importing CSS files
  • Styles support inheritance, so you can pull from a common parent and apply additional styles or override styles for specific elements
  • Style precedence is deermined from the element up, so if the element describes and style, then it overrides any named styles or TargetTypes
  • Inheritance accomplished by using “BasedOn={StaticResource parentStyleName}” on the Style definition
  • Styles can be tied to properties (and Events in WPF have reflecting properties, so by extension they can be tied to Events also)
  • DataBinding can be done at the Control or Container level, so you can specify a single Binding for an entire DataTemplate or Panel and then use it in child Elements
  • DataTemplate is like a mini-Window defined in XAML
  • DataTemplate places content in a ContentControl
  • The root Element is usuallya Panel, but can be anything
  • Anything goes regarding layout with a DataTemplate
  • Blend has a DataTemplate editor (why doesn’t VS have some of this stuff?)
  • A DataTemplate can have Triggers that change aspects of its display based on events and properties
  • They can be applied base don individual properties to any level Element

I have not seen it demonstrated, but after the presentation Billy confirmed that he has seen Vista Gadgets built on WPF. Man, the possibilities here are unbelievable. WPF really is the first GUI paradigm shift we’ve since the GUI was created.

3:10pm update – VS2008 Overview:

  • VS is a shell that hosts other Components
  • Because 3.0 and 3.5 build on 2.0, there is distinct support for each of these three frameworks in VS2008
  • 2008 Solution files are a little different than 2005
  • ASP.NET Web Applicaiton projects have AJAX support built in
  • Intellisense can be hidden by holding the CTRL key down (well, not really hidden, but it becomes translucent)
  • Intellisense is expanded and improved in VS2008: supports LINQ
  • JavaScript Debugging – use F9 to set breakpoints
  • Complete access to the Document object tree in debug
  • There is an ImmediateWindow for making and testing on the fly Script changes
  • WCF support is built in to VS2008
  • WPF Designer is built in to VS2008 (but investigate Blend)
  • WPF anchoring is controlled inside the designer window, not the properties grid
  • ClickOnce support enhaned
  • VS2008 also has XSLT debugging
  • XSLT breakpoints can be set in both theXSLT and the Data Source file
  • Web Apps have a Split Screen designer option
  • Support has been added for nested Master Pages

4:20pm update:

Attended a class on “Expression Blend for Developers” by Billy Hollis. Not really a lot of new information, but it did go into more detail and show some more hands on type use of Blend.

  • Blend is part of the Expression Suite, but Blend is included in MSDN. The rest of the suite is really meant for Graphics Designers.
  • Blend is the preferred tool for developing WPF and SilverLight UI.
  • Blend and Visual Studio share the same projects, so when you create a project in Blend you must select the Framework and Language targets even though you cannot develop code in Blend.
  • Blend is designed for Wide Format screens, so that will grant a better user experience than traditional aspect ratios.
  • Blend will execute code written in VS.
  • Grid is the default root element of any new WPF app in Blend, but it can be changed to other Panel types.
  • Grid Columns are better designed in VS than in Blend: the properties grid in VS makes setting column and row information easier while Blend only allows you to approximate sizes by eye on the design surface.
  • Otherwise, Blend is the superior tool for the UI development.
  • XAML editing in Blend does not have Intellisense (but VS does)
  • Blend has visual tools for creating DataTemplates and Styles and can save them as Resources, either for the Application, Windows, or a ResourceDictionary
  • Blend can set up DataBinding using a drop and drag technique

After all I’ve seen, between WPF and Blend, C# 3.5 and LINQ, all I can say is that I am going to have a lot of fun over the next few months.

Post session update:

The last session of the day was on the new Entity Data Model.? The keynote this morning had already hit most of the highlights, but in this session we actually got to see some of the tools and results.? And again, I am very impressed.? The technology is not ready for prime time (which is fitting since it won’t be released until spring), but it has great promise.? The point of it all is to be able to further abstract the database schema from the objects that use it.? EDM is all about abstraction: data mapping rules stored in XML files are how the complexity is managed.

Basically, the objects are defined as you would actually use them, with no regard to how they relate to database schema.? The framework then generates “go between” code to handle CRUD operations.? LINQ is used heavily to interface with the resulting Entities.? This will definitely be a technology to watch.? Here are some final bullets:

  • Can be done in VS2008, but you need to load the ADO.NET Entity Framework and tools separately
  • Provides graphical modeling of databases and Entities
  • The resulting Entities are then used in lieu of the actual DB connection (using the ADO.NET disconnected model).? In other words, you treat data like objects
  • One Entity can update multiple tables seamlessly, and the schema relationships are maintained
  • If the schema changes, must rerun the wizard to regenerate the new Entities. (unless you are a masochist who likes to do things manually)

More to come tomorrow.? Whew, these days can really wear you out!

Categories: .NET 3.5, C# 3.0, LINQ, WPF