Click here to Skip to main content
11,479,170 members (64,718 online)
Click here to Skip to main content
Articles » Languages » C# » General » Downloads
Add your own
alternative version

Dynamic Binding in C#

, 4 Feb 2011 Public Domain 45.4K 573 44
Illustrates a dynamic binding implementation in C#
DynamicBindingInCSharp.zip
Properties
<pre>
Title:       Enter Article Title Here
Author:      Type Your Code Project User Name
Email:       Type Code Project E-mail Login
Member ID:   12345 (seen from Settings, in URL "mid=12345")
Language:    Type Languages that Apply to Your Article (C# 3.0, etc.)
Platform:    Type Platforms that Apply to Your Article (Windows, etc.)
Technology:  Type Technologies that Apply to Your Article (WPF, etc.)
Level:       Pick ONE: Beginner/Intermediate/Advanced
Description: Enter a brief description of your article
Section      Type the Code Project Section you Wish the Article to Appear
SubSection   Type the Code Project SubSection you Wish the Article to Appear
License:     CPOL (default - select your desired license from our list)</pre>


<h2>Introduction</h2>

<p>This article will show you have to simulate dynamic binding in C#. </p>

<h2>Background</h2>

<p>To understand the meaning of dynamic binding, one can look at SRFI 39 which is 
  an implementation of a dynamic binding mechanism for R5RS Scheme. Dynamic 
  binding is also frequently used in LISP. Another commonly used dynamic binding is the 
  &#39;this&#39; keyword in JavaScript. For an in-depth explaination, please read chapter 2 
  of
  <a href="http://www.amazon.com/Lisp-Small-Pieces-Christian-Queinnec/dp/0521562473">
  LISP in Small Pieces</a> by Christian Queinnec.</p>
<p>To understand what this code does (in terms of dynamic binding), consider the following psuedo C# snippet:</p>
<pre lang="C#">
var orig-value = getvalue(location);
setvalue(location, new-value);
try
{
  <i>body</i>
}
finally
{
  setvalue(location, orig-value);
}
</pre>
<p>Firstly, it gets the original value, which is stored. Then it sets the value at 
  the location (property or field or a getter/setter method pair) to the new 
  value. Once the execution leaves the body part, the original value is restored 
  unconditionally. This means even in the presense of exceptions, the value is 
  faithfully restored.</p>
<p>Another aspect is the fact that dynamic bindings can be nested within one 
  another. For example, we can place the same construct within the <i>body</i> part.</p>
<p>This illustrates the essense of dynamic binding, and how it is implemented in 
  the code complementing this article.</p>


<h2>Using the code</h2>

<p>The code in the form of extension methods that is encapsulated in a single class. To 
  use the code, you can copy the class anywhere, and simply include the containing 
  namespace.</p>
<p>The &#39;API&#39; exposes 2 methods with 2 overloads each. </p>
<p>The Bind method does 
  a plain dynamic binding, while the With method allows the dynamic binding to be 
  disposed automatically when exiting the <i>body</i> of of the dynamic binding. Both 
  methods should be called in the <i>expression</i> part of the <code>using</code> construct in C#.</p>
<p>Use the following as a guide to the terminalogy used above and throughout the 
  article:</p>
<pre lang="C#">
using (<i>expression</i>)
{
  <i>body</i>
}
</pre>

<p />

  Each of the above methods provides an additional overloaded method taking an 
  <code>Expression&lt;Func&lt;T&gt;&gt;</code> argument for convinience. This allows one to build getter 
  and setter delegates for both properties and fields.

<p>Here follows the method signatures and documentation for the exposed methods:</p>
<pre lang="C#">
/// &lt;summary&gt;
/// Binds newvalue with getter and setter delegates
/// &lt;/summary&gt;
/// &lt;typeparam name="T"&gt;Inferred&lt;/typeparam&gt;
/// &lt;param name="newvalue"&gt;the newvalue to bind&lt;/param&gt;
/// &lt;param name="getter"&gt;delegate to get the value&lt;/param&gt;
/// &lt;param name="setter"&gt;delegate to set the value&lt;/param&gt;
/// &lt;returns&gt;an instance to wrap use in a using construct&lt;/returns&gt;
public static IDisposable Bind&lt;T&gt;(this T newvalue, Func&lt;T&gt; getter, Action&lt;T&gt; setter)
</pre>
<pre lang="C#">
/// &lt;summary&gt;
/// Binds newvalue with get/set property
/// &lt;/summary&gt;
/// &lt;typeparam name="T"&gt;Inferred&lt;/typeparam&gt;
/// &lt;param name="newvalue"&gt;the newvalue to bind&lt;/param&gt;
/// &lt;param name="locator"&gt;the locator, must be in the form () =&gt; instance.Property or () =&gt; Type.Property&lt;/param&gt;
/// &lt;returns&gt;an instance to wrap use in a using construct&lt;/returns&gt;
public static IDisposable Bind&lt;T&gt;(this T newvalue, Expression&lt;Func&lt;T&gt;&gt; locator)
</pre>
<pre lang="C#">
/// &lt;summary&gt;
/// Binds newvalue with getter and setter delegates and disposes the value when exiting the using construct
/// &lt;/summary&gt;
/// &lt;typeparam name="T"&gt;Inferred, must be IDisposable&lt;/typeparam&gt;
/// &lt;param name="newvalue"&gt;the newvalue to bind&lt;/param&gt;
/// &lt;param name="getter"&gt;delegate to get the value&lt;/param&gt;
/// &lt;param name="setter"&gt;delegate to set the value&lt;/param&gt;
/// &lt;returns&gt;an instance to wrap use in a using construct&lt;/returns&gt;
public static IDisposable With&lt;T&gt;(this T newvalue, Func&lt;T&gt; getter, Action&lt;T&gt; setter) where T : IDisposable
</pre>
<pre lang="C#">
/// &lt;summary&gt;
/// Binds newvalue with get/set property and disposes the value when exiting the using construct
/// &lt;/summary&gt;
/// &lt;typeparam name="T"&gt;Inferred, must be IDisposable&lt;/typeparam&gt;
/// &lt;param name="newvalue"&gt;the newvalue to bind&lt;/param&gt;
/// &lt;param name="locator"&gt;the locator, must be in the form () =&gt; instance.Property or () =&gt; Type.Property&lt;/param&gt;
/// &lt;returns&gt;an instance to wrap use in a using construct&lt;/returns&gt;
public static IDisposable With&lt;T&gt;(this T newvalue, Expression&lt;Func&lt;T&gt;&gt; locator) where T : IDisposable
</pre>

<h2>Usage examples</h2>

<p>The attached code contains several examples to illustrate the usage of this 
  dynamic binding implementation. In each of the examples, the original value will be restored after exiting the <code>using</code> construct's body.</p>
<p>The following class declarion will be used in some of the examples:</p>
<pre lang="C#">
class TestClass
{
  public string Test { get; set; }
  public static object StaticField;
}
</pre>
 
<h3>Instance property example:</h3>
<pre lang="C#">
var tc = new TestClass { Test = "Foo" };

Console.WriteLine(tc.Test);

using ("Bar".Bind(() =&gt; tc.Test))
{
  Console.WriteLine(tc.Test);

  using ("Baz".Bind(() =&gt; tc.Test))
  {
    Console.WriteLine(tc.Test);
  }

  Console.WriteLine(tc.Test);
}

Console.WriteLine(tc.Test);
</pre>
<h3>Static property example:</h3>
<pre lang="C#">
Console.WriteLine(Console.ForegroundColor);

using (ConsoleColor.Red.Bind(() =&gt; Console.ForegroundColor))
{
  Console.WriteLine(Console.ForegroundColor);
}

Console.WriteLine(Console.ForegroundColor);
</pre>
<h3>Local variable example:</h3>
<pre lang="C#">
var i = 0;

Console.WriteLine(i);

using (10.Bind(() =&gt; i))
{
  Console.WriteLine(i);
}

Console.WriteLine(i);
</pre>
<h3>Static field example:</h3>
<pre lang="C#">
Console.WriteLine(TestClass.StaticField);

using (10.Bind(() =&gt; TestClass.StaticField))
{
  Console.WriteLine(TestClass.StaticField);
}

Console.WriteLine(TestClass.StaticField);
</pre>
<h3>Getter and setter method pair example with sample extension:</h3>
<p>This example makes use of a helper extension method, called <code>AsConsoleOutput()</code>:</p>
<pre lang="C#">
/// &lt;summary&gt;
/// Redirects Console output temporarily within the using construct; can be nested
/// &lt;/summary&gt;
/// &lt;typeparam name="T"&gt;Inferred, must be TextWriter&lt;/typeparam&gt;
/// &lt;param name="writer"&gt;the writer to use&lt;/param&gt;
/// &lt;returns&gt;an instance to wrap use in a using construct&lt;/returns&gt;
public static IDisposable AsConsoleOutput&lt;T&gt;(this T writer) where T : TextWriter
{
  return writer.With(() =&gt; Console.Out, Console.SetOut);
}
</pre>
<p>Usage is then:</p>
<pre lang="C#">
Console.WriteLine("Console");

using (File.CreateText("warning.txt").AsConsoleOutput())
{
  Console.WriteLine("Warning");

  using (File.CreateText("error.txt").AsConsoleOutput())
  {
    Console.WriteLine("Error");
  }

  Console.WriteLine("Warning");
}

Console.WriteLine("Console");
</pre>
<h2>Points of Interest</h2>

<p>The implementation makes heavy use of LINQ Expressions, and <code>DynamicMethod</code> from System.Reflection.Emit for performance reasons.</p>

<p>The implemetation is only 152 lines long, including XML documentation comments, liberal whitespace and error checking.</p>

<p>Incidentally, Tomas Petricek of F# fame, just posted an implementation of this 
  in F# today after I &#39;announced&#39; my intentions. The snippet can be viewed @
  <a href="http://www.fssnip.net/2s">http://www.fssnip.net/2s</a>. Please note that I blatantly stole his ConsoleColor example :).</p>

<h2>History</h2>

<p>4 February 2011: Initial version.</p>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

Share

About the Author

leppie
Software Developer
South Africa South Africa
No Biography provided
Follow on   Twitter

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150520.1 | Last Updated 4 Feb 2011
Article Copyright 2011 by leppie
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid