Getting rid of strings (2): use lambda expressions

June 12, 2008 at 12:08 PMAndre Loker

Intro

In the first article of this series I talked about the problems with strings in code. This article will show you how you can use lambda expressions and expression trees as another tool to avoid strings.

About Lambda Expressions

C# 3.0 brought a cool new feature call lambda expressions. On the one hand they are a nice abbreviation for anonymous delegates:

   1: Button b = /*..*/
   2: b.Click += (sender, e) => MessageBox(String.Format("{0} clicked", sender);

But there's an additional feature that might not be obvious to everyone. .NET 3.5 introduced the System.Linq.Expressions namespace which allows us to inspect a code expression tree. One special expression type is Expression<TDelegate> which derives from LambdaExpression. This expression type handles the expression tree represented by a lambda expression. Let's look at an example:

   1: public class Program {
   2:  
   3:   public static void ExpressionTest(Expression<Func<DateTime>> expression) {
   4:     Console.WriteLine("Expression body is '{0}'", expression.Body);
   5:     Console.WriteLine("Node type is {0}", expression.Body.NodeType);
   6:     Console.WriteLine("Expression body type is {0}", expression.Body.GetType());
   7:   }
   8:  
   9:   public static void Main(string[] args) {
  10:     ExpressionTest(() => DateTime.Now);
  11:   }
  12: }

ExpressionTest expects an expression representing a Func<DateTime>, that is a function that returns a DateTime. In the Main method ExpressionTest is invoked - not with an Expression<Func<DateTime>> but simply with a lambda expression with the Func<DateTime> signature. The C# 3.0 compiler will convert the lambda expression that is passed as argument to a expression tree with a top node of type Expression<Func<DateTime>>. The Body property of that expression contains the right hand side of the lambda expression.

Running this code prints:

   1: Expression body is 'DateTime.Now'
   2: Node type is MemberAccess
   3: Expression body type is System.Linq.Expressions.MemberExpression

The runtime type of the expression body is MemberExpression, which makes sense, because DateTime.Now represents access to a member (Now) of DateTime. Run the code in the debugger to see how the expression is represented in the expression tree.

I won't go into too much detail on expressions here. Browse through the documentation of the Expressions namespace to see what kind of expressions you can expect (and inspect for that matter).

How can lambda expressions help to avoid strings?

Expressions can be useful in situations where you need to provide the name of a member or a MethodInfo/PropertyInfo/FIeldInfo for that member. Ever needed to pass a MethodInfo somewhere? You'll most likely ended up with something like

   1: var info = typeof (DateTime).GetMethod("ToShortDateSting");
   2: Console.WriteLine(info.Name);

This compiles fine, of course, but when you run the code you'll get a null pointer exception at info.Name. Why? Because there's a typo in "ToShortDateSting". The method I was looking for is ToShortDateString (realize the 'r' in String). Did you see the typo at a glance? The situation gets worse if the name of the method changes, because now the code would break at runtime without being changed (see the first article to learn about problems with strings and refactoring).

Captain Lambda to the rescue

Here's an approach that is much more solid:

   1: var info = Reflect.GetMethod<DateTime>(dt => dt.ToShortDateString());
   2: Console.WriteLine(info.Name);

No strings attached so to speak. If you had a typo in ToShortDateString the code would not even compile. Additionally, the code is much more open to refactoring. But wait, how does it work? Here's the simple answer:

   1: public static class Reflect {
   2:   /// <summary>
   3:   /// Gets the MethodInfo for the method that is called in the provided <paramref name="expression"/>
   4:   /// </summary>
   5:   /// <typeparam name="TClass">The type of the class.</typeparam>
   6:   /// <param name="expression">The expression.</param>
   7:   /// <returns>Method info</returns>
   8:   /// <exception cref="ArgumentException">The provided expression is not a method call</exception>
   9:   public static MethodInfo GetMethod<TClass>(Expression<Action<TClass>> expression) {
  10:     var methodCall = expression.Body as MethodCallExpression;
  11:     if(methodCall == null) {
  12:       throw new ArgumentException("Expected method call");
  13:     }
  14:     return methodCall.Method;
  15:   }
  16: }

GetMethod expects an expression with a delegate of type Action<TClass>, that is a void method having a TClass as it's only argument. GetMethod checks that the expression passed in is a method call by casting the body to a MethodCallExpression. If the cast succeeds, the Method property already contains the MethodInfo that we were looking for. Thank you C# 3.0 compiler for doing the work for us :-)

A more practical example

In MonoRail the Controller class has a method called RedirectAction which - well - redirects the response to a new action. It expects the name of an action as its argument. So you might see code like this:

   1: public class HomeController : Controller {
   2:   
   3:   public void Index() {
   4:     if(!UserIsLoggedIn){
   5:         RedirectToAction("Login");
   6:     }
   7:   }
   8:  
   9:   public void Login() {
  10:   }
  11: }

This works fine but of course it suffers from all the string related problems I have been talking about so far. Let's see if we can use our new friend (Expression<TDelegate>) to improve the situation:

   1: public static class ControllerExtensions {
   2:   public static void RedirectToAction<TController>(this TController controller, Expression<Action<TController>> expression) where TController : Controller {
   3:     var methodCall = expression.Body as MethodCallExpression;
   4:     if (methodCall == null) {
   5:       throw new ArgumentException("Expected method call");
   6:     }
   7:     controller.RedirectToAction(methodCall.Method.Name);
   8:   }
   9: }

Now we have an extension method that we can use instead of the original RedirectToAction:

   1: public class HomeController : SmartDispatcherController {
   2:  
   3:   public void Index() {
   4:     // RedirectToAction("Login");
   5:     this.RedirectToAction(c => c.Login());
   6:   }
   7:  
   8:   public void Login(){
   9:   }
  10: }

Is this cool or what? Once again we got rid of a string. You can redirect to a method with parameters as well:

   1: public void Index() {
   2:   this.RedirectToAction(c => c.ShowItem(0));
   3: }
   4:  
   5: public void ShowItem(int id){
   6: }

You can pass any value to the "call" to ShowItem that you like. Remember: the expression is only examined but not executed. If you want to pass an actual value to the redirected action, create extension methods for the RedirectToAction overloads that accept parameters. I won't show this here because it is not too hard to implement (and I'm only showing some examples here anyway).

Properties

You can also get a PropertyInfo (and similarly a FieldInfo) using Lambdas, here's an example:

   1: public static class Reflect {
   2:   public static PropertyInfo GetProperty<TClass, TValue>(Expression<Func<TClass, TValue>> expression) {
   3:     var memberExpression = expression.Body as MemberExpression;
   4:     if (memberExpression == null || !(memberExpression.Member is PropertyInfo)) {
   5:       throw new ArgumentException("Expected property expression");
   6:     }
   7:     return (PropertyInfo) memberExpression.Member;
   8:   }    
   9: }
  10:  
  11: // use:
  12: var dayProperty = Reflect.GetProperty<DateTime, int>(dt => dt.Day);
  13: Console.WriteLine(dayProperty.Name);

NB: the code shown above only works for properties that are not write-only (otherwise you will not be able to "return" the property value in the expression). I don't consider this a big limitations. How many write-only properties have you written in the past two months?

In the example above we have to provide both the type of the class as well as the type of the property. It makes the code slightly less elegant. We can improve it like this:

   1: public static PropertyInfo GetProperty<TClass>(Expression<Func<TClass, object>> expression) {
   2:     MemberExpression memberExpression;
   3:     // if the return value had to be cast to object, the body will be an UnaryExpression
   4:     var unary = expression.Body as UnaryExpression;
   5:     if (unary != null) {
   6:       // the operand is the "real" property access
   7:       memberExpression = unary.Operand as MemberExpression;
   8:     } else {
   9:       // in case the property is of type object the body itself is the correct expression
  10:       memberExpression = expression.Body as MemberExpression;
  11:     }
  12:     // as before:
  13:     if (memberExpression == null || !(memberExpression.Member is PropertyInfo)) {
  14:       throw new ArgumentException("Expected property expression");
  15:     }
  16:     return (PropertyInfo) memberExpression.Member;
  17: }
  18:  
  19: var dayProperty = Reflect.GetProperty<DateTime>(dt => dt.Day);
  20: Console.WriteLine(dayProperty.Name);
  21:  

It's a bit more complicated, but still understandable.

Update 07/22/2008: RednaxelaFX came up with a third alternative. GetProperty stays the same as in the first (simpler) version, but we call the method differently:

   1: // use:
   2: var dayProperty = Reflect.GetProperty( (DateTime dt) => dt.Day);
   3: Console.WriteLine(dayProperty.Name);

By providing the type of the expression's argument explicitly the compiler is now able to infer the return value of the expression. Thanks RednaxelaFX for your comment!

Summing it up

Lambda expression trees are a great to tool that allows us to point to members without using strings. There are some limitations, though:

  • It only works for "compile time reflection". The expression tree is created during compilation, so you cannot get the name of "some member" of "some type" at runtime.
  • It won't work with static members
  • It will only work for members that are visible in the context where the expression is built. Non-public fields, properties and methods can therefore be tricky using this technique.

Still there are plenty of situations where you need to provide the MemberInfo of a public instance method/property (or it's name) known at compile time.

Posted in: C# | Patterns

Tags: , , ,

Getting rid of strings (1): meet the villain

June 10, 2008 at 1:30 PMAndre Loker

Intro

This series covers the potential problems that arise from the use of string literals in source code. Avoiding string literals can make your source code more robust, more manageable and less fragile regarding refactoring. The articles in this series will show several solutions on how to replace string literals with smarter constructs.

The problem: meaningful strings

Strings in source code can be a tricky thing. How much depends on the content and the context. A "Hello, world!" that is spit out somewhere is not that much of a problem. The meaningful strings are the problematic ones. I consider a string meaningful if it contains a named entity in the source code (types, members etc.) or a named resource (configuration settings, embedded resources, file names).  Here are two examples of meaningful strings that can be tricky:

   1: string setting = ConfigurationManager.AppSettings["UserName"];
   2: MethodInfo info = typeof (Foo).GetMethod("Execute");

What's the deal with them? Generally, strings like these cause trouble if

  1. the string is used multiple times in the code
  2. the string literal has to be changed

In the first example the string "UserName" refers the key of an application setting, found in the <appSettings> element in the application/web configuration file. If you were to change the key for whatever reason you would have to hunt down all occurrences of "UserName" and replace them. While practically all modern IDE's and text editors provide a search and replace function over multiple files, blindly replacing all occurrences of "UserName" might also override instances of "UserName" that are in no way related to the configuration setting. For example "UserName" could be used as a filter criterion in an NHibernate query:

   1: public Account GetAccountByUserName(string userName){
   2:   ISession session = //.. get an NHibernate session
   3:   return session.CreateCriteria(typeof(Account))
   4:     .Add(Expression.Eq("UserName", userName))
   5:     .UniqueResult<Account>();
   6: }

Changing "UserName" to anything else will most likely cause an error at runtime.

In the second example "Execute" references the name of a method of some fictional type Foo. Refactoring tools are widely available these days, so renaming Execute to something different is done quickly. Changing the method name will brake the code, again at runtime. While decent refactoring tools will try to find the symbol being renamed in strings, relying on this feature suffers from the same problem as the one above.

How to handle strings: basic rules

The basic rules of using meaningful string literals in source code:

  1. Avoid them. If possible, simply don't use string literals which are meaningful and suffer from the problems described above.
  2. If the previous is not possible, at least remove all duplicate occurrences of the same string literal and replace them with a named symbol. Just like 'magic numbers', replace all string literals with the same meaning by a string constant with a descriptive name. For the first example above, one could introduce a static class containing the settings keys (see below)
  3. Hide the use of string literals and/or string constants behind an API. (see below)

For the first example (the app settings key), rule 2 could be applied like this:

   1: public class AppSettingsKeys {
   2:   public const string UserName = "UserName";
   3: }
   4: //...
   5: var userName = ConfigurationManager.AppSettings[AppSettingsKeys.UserName];

But maybe applying rule 2 and 3 is even better:

   1: public static class AppSettings {
   2:   const string UserNameKey = "UserName";
   3:  
   4:   public static string UserName {
   5:     get{ return Get(UserNameKey);}
   6:   }
   7:  
   8:   static string Get(string key) {
   9:     return ConfigurationManager.AppSettings[key];
  10:   }
  11:  
  12: }
  13: //...
  14: var userName = AppSettings.UserName;

The fact that we are dealing with strings to access the app settings is nicely hidden behind the API provided by AppSettings. (Note: a subsequent article of this series will show a much better way to access app settings).

In both examples if the key of the "UserName" app setting changed, only one string had to be updated (AppSettingsKeys.UserName or AppSettings.UserNameKey). The name of the string constant could be left alone or it could be easily renamed using refactoring tools.

Conclusion

This article gives a fairly basic overview of the problems that can occur when dealing with meaningful string literals in source code. The next parts of this series will cover more sophisticated techniques to get rid of strings.

Posted in: C# | Patterns

Tags: , ,

Arrange items in a list according to a list of keys

June 5, 2008 at 12:47 PMAndre Loker

Recently I needed an algorithm to change the order of elements in an item list of type IList<T>. The items had a unique key. The new order of the items was defined by a second collection which only contained the keys in the new order. Therefore, the algorithm had to move the elements in the IList<T> in such a way that their order matches the order of the key in the key collection.

To better illustrate the scenario, here's an example. Assume a domain object Person:

   1: public class Person {
   2:   public int ID { get; set; }
   3:   public string Name { get; set; }
   4: }

Say we have an array with Person instances:

   1: var people = new[]
   2: {
   3:   new Person{ID=1, Name="Jan"},
   4:   new Person{ID=2, Name="Piet"},
   5:   new Person{ID=3, Name="Klaas"},
   6: };

I now want to rearrange the order of the Person instances, given a second array which contains the keys of the items in the correct new order:

   1: var newOrderKeys = new[] {3, 1, 2};

That is, after rearranging the items, the following should hold:

   1: Assert.AreEqual(3, people[0].ID );
   2: Assert.AreEqual("Klaas", people[0].Name);
   3:  
   4: Assert.AreEqual(1, people[1].ID );
   5: Assert.AreEqual("Jan", people[1].Name);
   6:  
   7: Assert.AreEqual(2, people[2].ID );
   8: Assert.AreEqual("Piet", people[2].Name);

Here are some constraints and assumptions for the algorithm

  • The algorithm must not add or remove items from the list as it must be applicable to arrays (which do not allow appending or removing of items)
  • The keys must implement IEquatable<TKey>
  • Each key appear only once in the original list
  • The algorithm should gracefully handle errors in the key list, like
    • Duplicate keys
    • Too few or too many keys
    • Keys that don't exist in the original item list
  • If the number of distinct keys in the key list does not match the number of items in the item list, arrange only as many items as there are distinct valid keys (or at most itemList.Count items). If there are n valid distinct keys, the first min(n, itemList.Count) items should be arranged, all other items may be left in any order.

This was my first version:

   1: public static void Arrange<TItem, TKey>(this IList<TItem> items, IEnumerable<TKey> newOrderKeys, Func<TItem, TKey> keyExtractor)
   2:   where TKey : IEquatable<TKey> {
   3:   // index at which the next item will be placed
   4:   var writerIndex = 0;
   5:   foreach (var key in newOrderKeys.Distinct().TakeWhile(k => writerIndex < items.Count)) {
   6:     var index = -1;
   7:     // find the index of the item with the given key
   8:     for (var i = writerIndex; i < items.Count; ++i) {
   9:       // do keys match?
  10:       if (keyExtractor(items[i]).Equals(key)) {
  11:         index = i;
  12:         break;
  13:       }
  14:     }
  15:     if (index >=0) {
  16:       // swap the item with the one at the write index
  17:       // but only if the index of that item is higher than the 
  18:       // write index
  19:       if (index > writerIndex) {
  20:         var temp = items[index];
  21:         items[index] = items[writerIndex];
  22:         items[writerIndex] = temp;
  23:       }
  24:       // increase write index if element was found
  25:       ++writerIndex;
  26:     }
  27:   }
  28: }

It works like this:

  • First, remove duplicates from the newOrderKeys list (the key list), this is done with Distinct()
  • Limit the number of items to grab from the remaining list to he length of the item list lists. This is done with TakeWhile(). I could have used Take(items.Count), but this would count keys that are not found in the item list, so I chose to track the number of valid keys in writerIndex and compare this variable to items.Count. Note that Resharper gives a warning ("Access to modified closure") when accessing writerIndex in the lambda. In this case, this is no problem as the lambda invocation and increment of writerIndex take turns. Let's just say: it works :-)
  • For each item in the filtered and limited key list, find the index of the corresponding item in the item list items. All elements with an index less than writerIndex will have been arranged correctly, so start searching at index writerIndex.
  • If such an element was found, swap it with the item at writerIndex and increase writerIndex. As an optimization, do not swap if writerIndex == index.
  • The method is an extension method for IList<T>s, so usage is simple.

And here's how to use it:

   1: people.Arrange(newOrderKeys, p => p.ID);

Easy, isn't it? Just pass an enumeration with the keys in the new order and provide a function that maps from an item to a key.

Improvements

As you see the indices of the items are found by a linear search. For small lists this isn't a problem, for larger ones it can become really inefficient. A faster alternative is the use of a dictionary which stores the indices for each key in the item list. This dictionary can be easily created like this:

   1: var index = 0;
   2: var dict = items.ToDictionary(keyExtractor, item => index++);

This creates a dictionary of all keys in the item list mapped to the index in the list. Looking up the index is now easy and fast:

   1: if(!dict.TryGetValue(key, out index){
   2:   index = -1;
   3: }

I did some benchmarks and found that for lists with up to ~40 elements it is faster to simply use a linear search for the indices. Larger lists could benefit from the dictionary method. This looked like a good place for the Strategy Pattern. My final version (see attached file) therefore switched the strategy depending on the size of the collection.

Using a strategy for index lookup and refactoring element swapping out to a separate method the core of the arrange method becomes this:

   1: foreach (var key in newKeysOrder.Distinct().TakeWhile(k => writeIndex < items.Count)) {
   2:   var index = indexOf(items, writeIndex, key);
   3:   if (index >= writeIndex){
   4:     items.Swap(index, writeIndex++);
   5:   }
   6: }

indexOf is a delegate of type Func<IList<TItem>, int, TKey, int> that will return the index of the element in items that has the given key (given a start index as a hint).

What is it good for?

If you have read until here you might ask yourself where one would possibly use an algorithm like this. The place where I needed it is a web application which allowed the user to sort items using drag and drop (using jQuery's sortable feature). When the user has changed the order of the items in the browser, jQuery sends an AJAX request to the server that contains the keys of the items in the new sort order. The server uses the Arrange method to change the order of the items in its domain model.

I have put up a small example app that does a similar thing.

To the demo app.

You can change the order of the album tracks using simple drag and drop. jQuery will send the new order to the server which responds with the order as it is known by the server (this will allow you to compare client sort order with server sort order). The app uses MonoRail and the action that handles the AJAX request looks like this:

   1: public void UpdateOrder(string items) {
   2:   CancelView();
   3:   if (items == null) {
   4:     RenderText("Bad argument");
   5:   } else {
   6:     var album = GetAlbum();
   7:  
   8:     // parse ids from parameter
   9:     var ids = items.Split('&').Select(s => new Guid(s.Substring("item[]=".Length)));
  10:     // change order of album tracks according to order of GUIDs
  11:     album.Tracks.Arrange(ids, t => t.ID);
  12:  
  13:     RenderText("New order (on server): " + TitleOrderToList(album));
  14:   }
  15: }

The items parameters contains the IDs (GUIDs) of the tracks like this: "item[]=some-guid&itemp[]=some-guid&...".

The first cool thing is the way the Guids are extracted from the string, Then the Arrange method is used to let the model reflect the new sort order.

If you have any use for the code, use it, spread it, modify it any way you like. Don't blame me if explodes, though ;-)

Download the source code:

ArrangeList.cs (3.39 kb)

Update 6/9/2008:

JSK detected a small bug in the source code which caused the writeIndex not to be updated if an item already was in place. I fixed it in the article, the downloadable source code and the demo app. Thanks for spotting this!

Posted in: C# | Patterns | Snippets

Tags: , , ,

The beauty of fluent interfaces

May 15, 2008 at 11:43 PMAndre Loker

I notice that more and more frameworks, toolkits and libraries use fluent interfaces. Here are two examples:

Rhino Mocks

   1: [Test]
   2: public void SomeTest() {
   3:     var mocks = new MockRepository();
   4:     var service = mocks.CreateMock<IAccountService>();
   5:     using (mocks.Record()) {
   6:         Expect
   7:             .Call(service.Login(null, null))
   8:             .Constraints(Is.NotNull() & Is.NotSame("foo"), Is.NotNull())
   9:             .Repeat.AtLeastOnce()
  10:             .Return(LoginResult.Failed);
  11:         // ...
  12:     }
  13: }

Castle Windsor

   1: var container = new WindsorContainer();
   2: container.Register(
   3:     Component
   4:         .For<IAppContext>()
   5:         .ImplementedBy<AppContext>()
   6:         .Parameters(Parameter.ForKey("synchronized").Eq("true")));

[Maybe its not surprising that both libraries use fluent interfaces. Ayende Rahien, creator of Rhino Mocks, is also a huge contributor the the Castle project. ]

Most of the time I really like fluent interfaces. Not only does the code reveal its intention more clearly - at least most of the time. You also get support while writing the code: depending on the FI, the object returned by a call to an FI method might only a reduced set of methods that are meaningful at that point which drives you more into the correct direction.

If you write a FI for a library yourself, be sure to not overdo it. Keep it simple and don't try to get everything FI-esque just because you know how to do it. One possible pitfall of fluent interfaces is that it is not always clear how many times a method should be called. For example, imagine the case where you have a Client class that can have multiple order Objects, each containing multiple OrderLine objects. This resembles the example of Martin Fowler. You decide to provide an FI for the operation of adding configuring an order, like so:

   1: var c = new Client();
   2: c.AddOrder()
   3:     .WithLine(10, "Apple", 0.49m)
   4:     .WithLine(4, "Banana", 0.59m)
   5:     .ExpressDelivery();

This looks certainly more fluent than the "conventional" way:

   1: var client = new Client();
   2: var order = new Order();
   3: order.ExpressDelivery = true;
   4: var line = new OrderLine();
   5: line.Quantity = 10;
   6: line.UnitCost = 0.49m;
   7: line.Product = "Apple";
   8: order.AddLine(line);
   9:  
  10: line = new OrderLine();
  11: line.Quantity = 5;
  12: line.UnitCost = 0.59m;
  13: line.Product = "Banana";
  14: order.AddLine(line);
  15:  
  16: client.AddOrder(order);

However, in the FI it is not that obvious that ExpressDelivery() should be called only once. Maybe the user wants to deliver the order twice (ok, the example is bad). The non-fluent version does not have this potential confusion. No one would assign order.ExpressDelivery multiple times and expect it to generate multiple deliveries.

Still, I think this is a small price to pay compared with the improved readability gained by FI.

Of course, the non-FI example is a worst case scenario. For example, you could provide constructor arguments to OrderLine. With C# 3.0 and object/collection initializers the example can be approved even more:

   1: var client = new Client();
   2: var order = new Order {
   3:     new OrderLine {Quantity = 10, UnitCost = 0.49m, Product = "Apple"},
   4:     new OrderLine {Quantity = 5, UnitCost = 0.59m, Product = "Banana"}
   5: };
   6: order.ExpressDelivery = true;
   7: client.AddOrder(order);

I even find the object initializer more expressive than the WithLine FI. I'm really looking forward to all the future APIs that will leverage fluent interfaces and C# 3.0  syntax features.

Posted in: C# | Snippets

Tags: , ,

sizeof(char) vs SizeOf(char)

May 6, 2008 at 10:59 PMAndre Loker

This is weird.

   1: using System;
   2: using System.Runtime.InteropServices;
   3:  
   4: public class Program {
   5:     public static void Main() {
   6:         Console.Out.WriteLine("sizeof(char) = {0}", sizeof (char));
   7:         Console.Out.WriteLine("Marshal.SizeOf(typeof(char)) = {0}", Marshal.SizeOf(typeof(char)));
   8:     }
   9: }

 

Output:

   1: sizeof(char) = 2
   2: Marshal.SizeOf(typeof(char)) = 1

And here is why: Of course Marshal.SizeOf handles different character sets when strings fields in structures are marshalled. An interesting point is that when no character set is explicitly given, the CLR assumes CharSet.Ansi. As System.Char has no CharSet defined, SizeOf calculates the marshalled size assuming Ansi encoding. When the char is within a struct, the StructLayoutAttribute can be used and is honoured by SizeOf:

   1: using System;
   2: using System.Runtime.InteropServices;
   3:  
   4: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
   5: public struct Ex1 {
   6:     private char x;
   7: }
   8:  
   9: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  10: public struct Ex2 {
  11:     private char x;
  12: }
  13:  
  14: public class Program {
  15:  
  16:     public static unsafe void Main() {
  17:         Console.Out.WriteLine("sizeof(Ex1) = {0}", sizeof (Ex1));
  18:         Console.Out.WriteLine("Marshal.SizeOf(typeof(Ex1)) = {0}", Marshal.SizeOf(typeof (Ex1)));
  19:         Console.Out.WriteLine("sizeof(Ex2) = {0}", sizeof (Ex2));
  20:         Console.Out.WriteLine("Marshal.SizeOf(typeof(Ex2)) = {0}", Marshal.SizeOf(typeof (Ex2)));
  21:     }
  22: }
   1: sizeof(Ex1) = 2
   2: Marshal.SizeOf(typeof(Ex1)) = 1
   3: sizeof(Ex2) = 2
   4: Marshal.SizeOf(typeof(Ex2)) = 2

This looks more realistic again. sizeof(Ex1) both return the same size the structs occupy in memory (which is 2 bytes because of the unicode character). Marshal.SizeOf(typeof(Ex1)) return the marshalled size, which is 1 because I chose Ansi as the character set. Similarly, the marshalled size of Ex2 is 2 because of the unicode character set.

Posted in: C#

Tags: ,