In my previous post, I mentioned about Visual FoxPro being a weakly-typed, dynamic, object-oriented language, which also featured it’s own SQL (Structured Query Language), and a fast local database. When I got to C#, I found a language that was strongly-typed, object-oriented, with no easy way to perform queries, and very hard to create dynamic behavior. But let me brake that down, pretty much the way I did with FoxPro in the previous post:

Object-Oriented

Instantiate an object and call a method on it. Similar to the way I did in FoxPro, but with a key difference: the class name isn’t a string passed into a function!

[code language=”plain”]User user = new User();
user.SayHello();[/code]

SQL (Structured Query Language)?

In the first two versions of C# there was just no easy way to query things. But then we were presented with LINQ (Language Integrated Query) in version 3!!

[code language=”plain”]myCustomers = from c in customers
                           where c.Id == 1
                           select c;

customer = myCustomers.SingleOrDefault();

customer.Address
customer.PhoneNumber
[/code]

That was very similar to the way I could do a SELECT followed by a SCATTER in FoxPro. I loved it!

I didn’t like the way the code read, though, with the “select” coming at the end (after so many years of starting my queries with SELECT). Once I got over that, I started to appreciate the fact that I could write my queries like this:

[code language=”plain”]customer = customers.where(c => c.Id == 1).SingleOrDefault();
[/code]

Or even better, like this:

[code language=”plain”]Customer customer = customers.SingleOrDefault(c => c.Id == 1);
[/code]

“What does that have to do with the topic of this series?”, you might ask. Stay with me…

Strongly-typed

Consider the following code:

[code language=”plain”]var myVariable = 1234;
myVariable = “Woohoo!!”;   // Nope…
[/code]

Well, since C# is strongly-typed, knowing the type of data we get back from queries is very important. Take this example:

[code language=”plain”]var customers = customers
                 .SingleOrDefault(c => c.Id == 1)
                 .Select(c => new { Address = c.Address, PhoneNumber = c.PhoneNumber  });[/code]

When C# 3 introduced type inference, many developers were confused with the keyword var, thinking it meant “variant”; in other words, a variable declared as var should be assigned different types of data at will. That was not the case; var was just a way to tell the compiler “hey, the type of this variable will be whatever type I’m assigning to it as I declare it.”

With that said, in prior examples we were having the query return a Customer object. In the example above, on the other hand, we return some sort of list of anonynous objects, by using the new keyword without the name of a class, but giving it the properties and initial values we want on them. So we just told the compiler “I need a new object that has these properties with these values”. The compiler creates a class for us containing those properties; it is not a class created dynamically during runtime.

Now, let’s take that example a step further:

[code language=”plain”]var customers = customers
                  .SingleOrDefault(c => c.Id == 1)
                  .Select(c => new { c.Address, c.PhoneNumber  });

customers = “can’t do this!”;
[/code]

Again, we declare a customers variable, and let the compiler infer its type. Next, we try to assign some string content to that same variable. The compiler yells at us, proving that var does not mean variant.

Dynamic (before C# Dynamic)

Let’s now have a look at how we implement dynamic things before the so-called “C# Dynamics” were introduced. Let’s revisit this simple sample:

[code language=”plain”]User user = new User();
string hello = user.SayHello();
Console.WriteLine(hello);
[/code]

What if we didn’t know during compile time what type of User to instantiate? And what if we only knew during runtime what method to execute? The way to that back then was only by using .NET Reflection, like so:

[code language=”plain”]var instanceType = Type.GetType(“Playground.User”);            
object instance = Activator.CreateInstance(instanceType);            

MethodInfo theMethod = instanceType.GetMethods().SingleOrDefault(m => m.Name == “SayHello”);           
object hello = theMethod.Invoke(instance, null); 
           
Console.WriteLine(hello.ToString());
[/code]

That way, both the class and method names where represent by strings. When doing that, we always work with object; that’s what the Activator’s CreateInstance method returns, and it’s also what the Invoke method on a MethodInfo instance returns. Using type inference here (declaring the variables with var) wouldn’t help us much.

Another option to create some sort of dynamic code back then was by emitting IL (Intermediate Language). Not exactly a fun thing to do. There are good cases for it, though, so check out some real world users of Reflection.Emit.

Yet another option, which I’ve used at least twice in successful projects, was to build C# code as strings within the application, and handle it over to the C# compiler during runtime. What type of code got created dynamically was controlled within the application, and it was executed within a sandbox, so the end-users couldn’t really “do anything they wanted”. In fact, I have used this approach in conjunction with the dynamic features once they become available.

Coming up next, dynamic code after the C# dynamic features arrived. Stay tuned!

One response to “Fun with C#: Before there were dynamic features”

  1. […] « Fun with C#: Before there were dynamic features […]

Leave a Reply

Trending

Discover more from Claudio Lassala's Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading