Aggregated Interface Implementation

I've been struggling around the aggregation used in WCF's Binding object model, as implemented in the GetProperty<T> method (see relevant discussions with Nicholas Allen from the WCF team here and here), and I'm struck by how the need for a flexible, late-bound way of extracting information from a composite object forces us to write ugly code.

Let's say I have an object myObject. myObject doesn't implement any interfaces, but it contains a list called elements that contain various other objects, each of which might implement those interfaces. Now lets say I want to get a handle to one of those interfaces - to make things more concrete, let's say we want the ISecurityProvider interface. Using the current WCF model, we would do something like this:

ISecurityProvider sec =  myObject.GetProperty<ISecurityProvider>();

Which in turn would do something like this:

T GetProperty<T>() where T : class
{
   T prop =
null;
  
foreach (object o in elements)
   {
     
if (o is T)
      {
         prop = (T)o;
        
break;
      }
   }
  
return prop;
}

(Remember, this is a simplified version. The actual WCF implementation is more complicated).

Now, what I would like to see, as a simplified and cleaner syntax, is the ability to do this:

ISecurityProvider sec = myObject as ISecurityProvider;

This is much clearer, adhers to the interface-implementation paradigm, and still allows me to make late-bound changes to my object's implementation. Ideally, the casting operation would internally call the GetProperty<T> method. The definition would go something like this:

public static explicit operator <T> (Aggregator agg)
{
  
return agg.GetProperty<T>();
}

Unfortunately, C#'s syntax doesn't allow for generic type parameters in operator overloading statements, so this can at most be a feature request - and I'm not entirely sure it's a justified one. Mostly a pipe dream. :)

A question that immediately pops up is what benefit does this give us over the GetProperty<T> syntax. The simple answer is uniformity - if I have code right now that checks a list of objects to see if they implement an interface, it will still work without having to make manual changes.

The downsides? I can think of several. First of all, this will require much more work than simply allowing generic cast operators in order to make the feature worthwhile. These aggregated implementations are naturally invisible to Reflection since they're relevant only at run-time. But what about the is operator? Currently it's ultra-quick and relies on an intrinsic CLR operation. Expanding that operation to look for aggregated implementations would naturally be a serious perfomance problem, but leaving it as is will seriously limit the usefulness of the feature since I have to constantly be aware of different results between is checking and explicit casting.

In short, while I think my idea has a certain amount of charm I don't think it's entirely usable. I won't be opening a language feature request for it on Connect, but I'd love to hear feedback and ideas about it.

3 Comments

  • AvnerK said

    Thanks - I made some last minute changes using Community Server's HTML editor rather than the rich-text editor, and it has the annoying tendency to occasionally repeat whole sections. Bah.

  • Marc Brooks said

    If all you are after is variability of method based on the type, you CAN get the compiler to disambiguate if you give it enough information. In the case of something like the properties, you probably know a reasonable default value if it's missing. By passing that default value, you can give the compiler the information it needs... for example: public static T This(Aggregator agg, T defaultValue) { return agg.GetProperty(); } Not quite what you're after, but close?

Comments have been disabled for this content.