You learn something new every day


I encountered something today in C# that I’ve never seen before and it caught me off guard.  In looking at the WSE 2.0 samples to understand how the transport mechanisms have changed, I came across the following in StockService:

Uri uri = new Uri(“soap.tcp://” + System.Net.Dns.GetHostName() + “/StockService”);

SoapReceivers.Add( uri, typeof(StockServiceRequestReceiver) );

You’re probably wondering, “What’s the big deal, Hambone?”  On the surface, this doesn’t seem so odd until you look at the method signature for SoapReceivers.Add:

public static void Add(EndpointReference, SoapReceiver);

public static void Add(EndpointReference, Type);

public static void Add(EndpointReference, SoapReceiver, bool);

public static void Add(EndpointReference, Type, bool);

Nowhere does SoapReceiers.Add take a System.Uri, yet that’s what’s being passed in above.  What makes this possible is an implicit operator on EndpointReference that takes a Uri:

public static implicit operator EndpointReference(Uri uri)

{

      return new EndpointRefernece(uri);

}

I hate to admit that I was responsible for conducting a number of classes internally on C# and a) never brought this up and b) it was never mentioned.  In fact, this is the first time I’ve actually seen this in use.  I’m interested in your feedback … how many of you use this C# feature in your development, and to what effect?

 


Comments (5)

  1. Nick Hodges says:

    Yowch! That’s not really typesafe. Maybe C# isn’t as typesafe as it claims. Operator overloading shouldn’t allow that type of side effect.

  2. On the surface, it may appear that it’s not really typesafe, but it still is. It’s not taking a Uri and casting it to an EndpointRefernece, rather it’s instantiating a new EndpointReference from a Uri. The end result is that when you access the object you’re always accessing it as the type you’ve told the compiler.

    It’s the same as saying:

    EndpointReference e = new EndpointReference(uri);

    SoapReceivers.Add(e, typeof(StockServiceRequestReceiver));

    It just looks really funky and I personally wouldn’t advocate anyone actually using it for the the many confusing reasons this creates.

  3. Very interresting. And yes, Kevin, you were great at conducting these internal C# courses 😉

  4. Nick Hodges says:

    <i>It’s the same as saying:

    EndpointReference e = new EndpointReference(uri);

    SoapReceivers.Add(e, typeof(StockServiceRequestReceiver));

    </i>

    Well, yes, but that’s the point — it’s taking one type an making it into another without you asking to do that. If you want the above code, then code it. The language/compiler/framework shouldn’t allow that type changed to take place without your permission. That doesn’t fit my definition of type safe.

  5. Mehul says:

    Hi

    I am trying to use SoapReceivers.Add and trying to use the EndpointReference as you said.

    But i get this error :

    The type or namespace name ‘EndpointReference’ could not be found (are you missing a using directive or an assembly reference?)

    I am just putting this:

    public static implicit operator EndpointReference(Uri uri)

    {

    return new EndpointRefernece(uri);

    }

    in the same class as i am using the SoapReceivers.Add

    Can someone please tell me more about how i get this to work?

    Thank you

    Mehul