Archive for April, 2017

Fun with C#: After dynamic features arrived

Today I’ll continue with our series on dynamic stuff, taking it from where we left off in our previous post. So, building on top of the same simple examples, let’s see what changed for me once the dynamic features arrived to C#.

Bending strong typing

Remember how C# is strongly-typed?

var myVariable = 1234;
myVariable = “Woohoo!!”;   // Nope...

We can bend that rule if we declare types as dynamic:

dynamic myVariable = 1234;
myVariable = “Oh, boy…”;

Yes, I hope you can see how writing code like that can cause all sorts of trouble. But, it does come in handy when we have good use for it. Anyway, when we declare something as dynamic, we’re telling the C# compiler “look, the actual type of this will have to be determined during runtime”. Of course, in the sample above, we have an integer and string, so it wouldn’t make sense at all to use dynamic there. However, in real world apps, the actual value types would only be known during runtime.

Now, take this example:

var names = new[] { "Claudio", “Paul" };
var result = names.Select(n => new { Length = n.Length }).ToList();
Console.WriteLine(result.GetType().Name); // List’1 

Notice that the type of result is List’1, because we’re projecting the items into new anonymous types, and using var to let the compiler infer the type.

So what happens if we changed the code to this:

dynamic result = names.Select(n => new { Length = n.Length }).ToList();
Console.WriteLine(result.GetType().Name);  // List’1

By changing the type of the variable to dynamic we told C# the type would only be known during runtime. Regardless, in that case, the type still ends up being List’1 at runtime.

What if we follow that code with this:

result = “Woohoo";
Console.WriteLine(result.GetType().Name);  // string

The type of result would be changed to string, which proves the data type is indeed dynamic.

The ever expanding object

As part of the dynamic features, we also got an ExpandoObject class. If we instantiate that class and type the variable to either ExpandoObject or var, we get access to the members of that class that were statically typed. But the real fun comes in when we type the variable to dynamic. Check this out:

dynamic user = new ExpandoObject();            

user.FirstName = "Claudio”;            
user.LastName = "Lassala”;            

user.FullName = new Func(() => $"{user.FirstName} {user.LastName}");            

Console.WriteLine(user.FullName()); 

In the example above, the FirstName and LastName are properties we added dynamically to that user object. FullName is a method that returns a string.

We could also have defined the FullName method before defining the other properties:

dynamic user = new ExpandoObject();         

user.FullName = new Func(() => {0}#x22;{user.FirstName} {user.LastName}");

user.FirstName = "Claudio”;            
user.LastName = "Lassala”;             

Console.WriteLine(user.FullName()); 

That would still work just fine, given that during runtime, when FullName() was called for the first time, the properties it depends on would already have been added to the object. What if the properties weren’t there already? It’d throw an exception, which we can handle gracefully.

Let’s revisit a sample from previous posts and make it use dynamic:

var instanceType = Type.GetType("Playground.User");            
dynamic instance = Activator.CreateInstance(instanceType);            
object hello = instance.SayHello();            
Console.WriteLine(hello.ToString());

The main change there is that we assign the return of CreateInstance to a dynamic variable. From there on, we can call methods on it that the compiler doesn’t know about during compile time. NOTE: this feature was great when working with Excel automation!!!

Now that we know all of that, going back to the idea that I wanted to instantiate classes and call methods for which I have strings that represent their names (these strings are likely coming from a database or configuration file, for instance). So I’d like to be able to write something like this:

dynamic instance = MakeObject("Playground.User");            
dynamic result = instance.Call("SayHello");            
Console.WriteLine(result);

That’s an easy thing to pull off now that we know about ExpandoObject and dynamic types. Here’s the implementation of MakeObject:

private static dynamic MakeObject(string className)
{    
    var instanceType = Type.GetType(className);    
    dynamic instance = Activator.CreateInstance(instanceType);    

    dynamic expando = new ExpandoObject();    

    expando.Call = new Func((methodName) =>    
    {        
        IEnumerable methods = instance.GetType().GetMethods();        
        var method = methods.SingleOrDefault(x => x.Name == methodName);        
        return method.Invoke(instance, null);    
    });                
    return expando;
}

So we use Reflection to instantiate the given type, add a Call method to an ExpandoObject, which in turn calls the method we want on the real object, also using Reflection, and things just work!

Using Reflection in this case is just one option. If this approach presents a performance issue, the Reflection part can be replaced with other alternatives (IL emit, dynamic compilation of code, building Expression Trees), but the client code of this functionality wouldn’t have to change: it’d still be using strings to know the name of the class to instantiate and the name of the method to call on the object.

This series will continue, as there’s quite a number of some other useful things we can do with this knowledge acquired so far!

Advertisements

2 Comments

Fun with C#: Before there were dynamic features

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!

User user = new User();
user.SayHello();

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!!

myCustomers = from c in customers 
                           where c.Id == 1 
                           select c;

customer = myCustomers.SingleOrDefault();

customer.Address 
customer.PhoneNumber 

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:

customer = customers.where(c => c.Id == 1).SingleOrDefault();

Or even better, like this:

Customer customer = customers.SingleOrDefault(c => c.Id == 1);

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

Strongly-typed

Consider the following code:

var myVariable = 1234;
myVariable = “Woohoo!!”;   // Nope...

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

var customers = customers 
                 .SingleOrDefault(c => c.Id == 1)
                 .Select(c => new { Address = c.Address, PhoneNumber = c.PhoneNumber  });

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:

var customers = customers 
                  .SingleOrDefault(c => c.Id == 1)
                  .Select(c => new { c.Address, c.PhoneNumber  });

customers = “can’t do this!”;

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:

User user = new User();
string hello = user.SayHello();
Console.WriteLine(hello);

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:

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());

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!

Leave a comment

Fun with C#: Dynamic Features – Why did I care?

I was glad to see dynamic features available in C# back when version 4 came out (in 2010, if memory serves me right…). But, why did I care?

Back in my old days, prior to start working with .NET, I was working heavily on Visual FoxPro projects. FoxPro was a weakly-typed, dynamic, object-oriented language, which also featured it’s own SQL (Structured Query Language), and a fast local database. Now, what does all mean?

Object-Oriented

I could define a class (say, “User”), instantiate it, and call methods on it (such as, “SayHello”):

SQL (Structured Query Language)

FoxPro allowed me write code like this:

SELECT Address, PhoneNumber FROM C:\DB\CUSTOMERS.DBF 
    WHRE Id = 1 
    INTO C:\TEMP\TEMP_CUSTOMERS.DBF 

No need to create a connection to a database: I could simply query some data off of a local file, and even dump into to another local file.

I could also create an object out of the current row off my query results, with properties matching the columns in the table (think Entity Framework reading data off a database and pushing into objects for you):

SCATTER NAME customer 
customer.Address 
customer.PhoneNumber 

 

Weakly-typed

We could assign an integer to a variable in one line, and then assign a string to it in another, and FoxPro was happy:

myVariable = 1234 
myVariable = “Woohoo!!”

Nope, that wasn’t necessarily a good thing, as people definitely abused that possibility. However, there were scenarios where it came in handy.

Dynamic

I could do the following:

1. Put the name of a class to instantiate and the name of a method to call in a string (both could be coming from a database):

className = “User”
methodName = “SayHello"

2. Merge those variables to another string variable representing lines of code:

text to someVariable texmerge noshow 
        instance = CreateObject(“<< className >>”)
        result = loInstance.<< methodName >>()
        MessageBox(result)
endtext 

3. Execute the code contained in that string variable like so:

&someVariable 

 

Putting it all together

So it was common to see code somewhat like this:

SELECT ClassName, MethodName 
    FROM WhateverTable 
    WHERE Module == “Hello World”

SCATTER NAME behavior 

text to someVariable texmerge noshow 
        instance = CreateObject(“<< behavior.className >>”)
        result = loInstance.<< behavior.methodName >>()
        MessageBox(result)
    
        result = 1234 
        MessageBox(result)
endtext 

&someVariable 

In reality, some FoxPro projects store entire modules created based off dynamic code like the one above, stored in databases.

Rewriting FoxPro “dynamic” software in .NET

I’ve worked in projects where the client wanted those FoxPro “dynamic” applications rewritten in .NET. I’ve been told many times that “our application is 100% dynamic; everything can be configured by the end-user”. I’ve even blogged about that. In the end, not everything was dynamic, but there were dynamic parts, indeed:

Users could:

  • Extend the system by adding new tables (but always based off existing ones);
  • Add columns to existing tables
  • Define what columns show on the grid
  • Define how columns, rows, and cells where displayed (background color, enable/disable, header, etc.)
  • Create CRUD screens for those columns they added;
  • Create reports using those new columns;
  • Create “expressions” that are evaluated in several situations (enabling/disabling a field, setting the default value of a field based off other fields, etc.). For example, maybe the default value for a new “Total” column in a table should be the result of the following expression (imagine that both Price and Quantity are also columns added by the user):
    • context.Product.Price * context.Item.Quantity
  • Etc.

Reproducing some of those pieces in C# wasn’t exactly easy back then, so this posts answers why I cared about the dynamic features introduced in C# several years ago.

In the next post I’ll go over what I did before the dynamic features of C# came around.

Leave a comment