C#, Lambdas / Anonomous delegates

A little var love

As we all know one of the things that LINQ gives us is anonymous types that can be

used by using the selection query operator, such as

 

   1:  var x = new { DateNow = DateTime.Now };
 
 
Which will give us an anonymous type with a single DateTime property called 
"DateNow", which is all cool. This is largely thanks to the "var" keyword. 
 
If you spend time working with the var keyword you will soon realise that 
you can no longer work with the object that is declared as a "var" as a 
strongly typed object outside the scope of the current method. 
 
We can get around this by using the object type as a parameter where a 
anonymous parameter could be passed. This is demonstrated in the following 
screen shot. As we can see we are able to pass an anonymous type, but from
there we have an object type, so the only way to get at the values is by 
using Reflection.
 
 
image 
 
Here is an example that shows we can obtain the value of anonymous 
types, well enough.
 
 
image 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 
Anonymous can't be used as method results, unless the method return 
type is object. This is why anonymous types should only be used 
locally within methods. One place where this rule is broken is 
within generic methods. 
 
Consider the following example code.
 
   1:          /// <summary>
   2:          /// Simple generic method
   3:          /// </summary>
   4:          public static TResult 
   5:              HaveSomeGenericFun<TResult>(Func<TResult> input)
   6:          {
   7:              return input();
   8:          }
   9:   
  10:          static void Main(string[] args)
  11:          {
  12:              //I am calling a generic method here passing it an 
  13:              //anonomous type....curious
  14:              var obj = HaveSomeGenericFun(
  15:                  () => new 
  16:                      {   
  17:                          Time = DateTime.Now, 
  18:                          ProcessName = 
  19:                              Process.GetCurrentProcess().ProcessName 
  20:                      });
  21:   
  22:              Console.WriteLine(String.Format(
  23:                  "Process {0} was running at {1}", 
  24:                  obj.Time, obj.ProcessName));
  25:   
  26:              Console.ReadLine();
  27:          }
 
The return type of the HaveSomeGenericFun is generic. If we call it 
without specifying a type for TResult, it is automatically inferred from 
the signature of the "input" parameter. Because the "input" Func<TResult> 
provided as an argument returns an instance of an anonymous type, 
the HaveSomeGenericFun() generic method returns that type. 
 
As can be seen that the HaveSomeGenericFun() method doesn't use an object 
return value anywhere, so the return value will be strongly typed.
 
Whilst this is all well and good and pretty useless by and large, LINQ uses 
this mechanism internally, and I just thought it was pretty interesting so 
thought it may be worth a mention.
 
So there you have it, consider it mentioned.
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Advertisements
C#, CodeProject, WPF

How To Bind To Generic Method In XAML

As some of you that have worked with XAML and Generics may know, there is currently no support for Generics in XAML (that is no support for direct binding of methods that use generics).

So consider this problem

That I have various bits of static data that are used through out the system, that are held as a collection(s) (I am using ObservableCollection) of certain data objects. The WPF UI should be able to bind to these collections, without the need for loads of get {…} properties. Ideally there would be a single method that returned the correct type of static data, as requested by the method. I mean there may be a lot of static data, and sure we could do this by exposing lots of properties over the static data collections, but that somehow seems old fashioned to me. We could of course also just take an Object and return a ObservableCollection, but that to seemed wrong, not enough typing more my liking there. The problem seems to warrant a more generic solution. Wait, doesn’t .NET support generics. Hell yeah, ok cool. So possibly we should be trying for something like the following after all:

   1:  public ObservableCollection<T> GetForType<T>()
   2:  {
   3:      return (ObservableCollection<T>)
              typeToCollectionLookup[typeof(T)];
   4:  }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

This seems to fit the problem domain, but how could we do this in XAML.

Unfortunately I do not know a way of dealing with generic method calls in XAML. I know there is a ObjectDataProvider object which has a Method property and allows parameters to be built up in XAML. But this would mean we would need one new ObjectDataProvider with parameters for each type we intended to use the above method for. That’s pretty poor. There must be a better way, surely.

Shown below is an attached property that could be used with a ComboBox control to bind to which will populate the ComboBox.ItemsSource property by calling the generic method.

So all you have to do in the XAML is

   1:  <Window x:Class="GenericBinding.Window1"
   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:      xmlns:local="clr-namespace:GenericBinding;assembly="
   5:      Title="Window1" Height="300" Width="300">
   6:      <Grid>
   7:  
   8:  
   9:          <ComboBox
  10:         local:ComboBoxProps.BoundCollectionType="local:Person"/>
  11:  
  12:  
  13:      </Grid>
  14:  </Window>

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Where the ComboBoxProps.BoundCollectionTypeProperty attached property is declared liked this

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Windows;
   6:  using System.Windows.Controls;
   7:  using System.Reflection;
   8:  using System.Collections;
   9:  
  10:  namespace GenericBinding
  11:  {
  12:      /// <summary>
  13:      /// Provides a mechanism for binding a ComboBox.ItemSource against
  14:      /// a generic method within the StaticData singleton. Where the generic
  15:      /// method has a signature as follows:
  16:      /// 
  17:      /// public ObservableCollection<T> GetForType<T>()
  18:      /// </summary>
  19:      public class ComboBoxProps
  20:      {
  21:          #region BoundCollectionType
  22:  
  23:          /// <summary>
  24:          /// BoundCollectionType Attached Dependency Property
  25:          /// </summary>
  26:          public static readonly DependencyProperty
                   BoundCollectionTypeProperty =
  27:              DependencyProperty.RegisterAttached(
                   "BoundCollectionType",
  28:              typeof(Type), typeof(ComboBoxProps),
  29:                  new FrameworkPropertyMetadata(null,
  30:                      new PropertyChangedCallback(
                            OnBoundCollectionTypeChanged)));
  31:  
  32:          /// <summary>
  33:          /// Gets the BoundCollectionType property.  
  34:          /// </summary>
  35:          public static Type GetBoundCollectionType
                     (DependencyObject d)
  36:          {
  37:              return (Type)d.GetValue(
                       BoundCollectionTypeProperty);
  38:          }
  39:  
  40:          /// <summary>
  41:          /// Sets the BoundCollectionType property.  
  42:          /// </summary>
  43:          public static void SetBoundCollectionType(
                     DependencyObject d, Type value)
  44:          {
  45:              d.SetValue(BoundCollectionTypeProperty, value);
  46:          }
  47:  
  48:          /// <summary>
  49:          /// Handles changes to the BoundCollectionType property.
  50:          /// Uses Reflection to obtain the method within the StaticData singleton class
  51:          /// that has the generic method that we need to use to get the values from.
  52:          /// The method will be marked with a custom ItemsSourceLookUpMethodAttribute
  53:          /// to indicate which method is to be used, to create a Dynamic call to
  54:          /// using the correct generic parameter.
  55:          /// </summary>
  56:          private static void OnBoundCollectionTypeChanged(DependencyObject d,
  57:              DependencyPropertyChangedEventArgs e)
  58:          {
  59:              ComboBox cbSource = d as ComboBox;
  60:              Type t = (Type)e.NewValue;
  61:              Type[] types = new Type[] { t };
  62:  
  63:              MethodInfo[] methods =
  64:                  typeof(StaticData).GetMethods(BindingFlags.Public |
                       BindingFlags.Instance);
  65:  
  66:              foreach (MethodInfo method in methods)
  67:              {
  68:                  //Didnt like looking up MethodInfo.Name based on a string as it could
  69:                  //change, so use a custom attribute to look for on the method instead
  70:  
  71:                  ItemsSourceLookUpMethodAttribute[] attribs =
  72:                      (ItemsSourceLookUpMethodAttribute[])
  73:                          method.GetCustomAttributes(
  74:                              typeof(ItemsSourceLookUpMethodAttribute), true);
  75:  
  76:                  //is this the correct MethodInfo to invoke
  77:                  if (attribs.Length > 0)
  78:                  {
  79:                      // create the generic method
  80:                      MethodInfo genericMethod = method.MakeGenericMethod(types);
  81:                      cbSource.ItemsSource =
  82:                          (IEnumerable)genericMethod.Invoke(StaticData.Instance,
  83:                          BindingFlags.Instance, null, null, null);
  84:                  }
  85:              }
  86:          }
  87:          #endregion
  88:      }
  89:  }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }If you want to see a full example you can read more about this on the codeproject article link shown below

http://www.codeproject.com/KB/WPF/GenericXAML.aspx

Hope this helps you as much as it did me. Enjoy

C#, Lambdas / Anonomous delegates, WCF, WPF

Dynamic LINQ To Entities Queries Using WCF/WPF demo code

I have been working on an article for Codeproject for a while now, and I have just finished it. You can read more about this article at the codeproject link :Dynamic LINQ To Entities Queries Using WCF/WPF demo code

Those of you that have used LINQ to SQL may know that you can use variables and Func<T,TResult> against a LINQ DataContex, but may not realise that you can not serialise a Func<T,TResult> and that the “var” keyword is only method level scope.

This article talks about one possible approach of how to create dynamic queries against the LINQ to Entities framework, that are able to be sent across a WCF service domain boundary. The article uses a WPC Client that creates a dynamic query based on some reflection, which is then sent to a WCF service. The actual WCF service is hosted within a Windows service, and the WCF service will call the LINQ to Entities framework that in turn is setup to look at the SQL Server Northwind sample database.

I have gone through a fair ammount of extra WCF stuff/Windows service hosting in the article, so you may find some other information too.

Anyway hope its useful to someone.