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

  • Anonymous
    December 14, 2003
    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.
  • Anonymous
    December 15, 2003
    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.
  • Anonymous
    December 15, 2003
    Very interresting. And yes, Kevin, you were great at conducting these internal C# courses ;-)
  • Anonymous
    December 15, 2003
    <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.
  • Anonymous
    September 23, 2005
    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