views:

238

answers:

2

This works:

EndPoint endPoint = new IPEndPoint(_address, _port);
_socket.ReceiveFrom(buffer, 0, 1024, SocketFlags.None, ref endPoint);

But this does not:

IPEndPoint endPoint = new IPEndPoint(_address, _port);
_socket.ReceiveFrom(buffer, 0, 1024, SocketFlags.None, ref endPoint);

(Note the type of endPoint)

Which seems odd. Why does the ref keyword break parameter contravariance?

+15  A: 

Because in the method signature, the endPoint parameter is declared as EndPoint, not IPEndPoint ; there is no guarantee that the method won't set endPoint to another kind of EndPoint, which would not be assignable to a IPEndPoint variable.

For instance, assume you have a FooEndPoint class that inherits from EndPoint, and a Foo method that takes a ref EndPoint parameter :

public class FooEndPoint : EndPoint
{
   ...
}

public void Foo(ref EndPoint endPoint)
{
    ...
    endPoint = new FooEndPoint();
    ...
}

If you were able to pass a IPEndPoint to that method, the assigment of a FooEndPoint to the endPoint parameter would fail at runtime, because a FooEndPoint is not a IPEndPoint

Thomas Levesque
I understand the logic behind your response and why they could decide to make a rule on this however I believe I'd agree with the poster since he's asking the question in the first place that it's an incorrect rule. The compiler at most should provide a warning that it's possible for an incorrect runtime assignment. But it should be left up to the developers to handle some type of incorrect exception instead of not being allowed.
Chris Marisic
Is this one of things that is addressed with the dynamic keyword in 4.0?
Chris Marisic
For a more extensive explanation, check out this post by Eric Lippert: http://blogs.msdn.com/ericlippert/archive/2009/09/21/why-do-ref-and-out-parameters-not-allow-type-variation.aspx
Thomas Levesque
+2  A: 

Because the method ReceiveFrom can create a new EndPoint - but not IPEndPoint. This parameter works kind of in two ways, so the type needs to match exactly.

Grzenio