Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are ref parameters not contravariant?

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?

like image 960
Jan Bannister Avatar asked Dec 01 '22 07:12

Jan Bannister


2 Answers

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

like image 64
Thomas Levesque Avatar answered Dec 06 '22 10:12

Thomas Levesque


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.

like image 23
Grzenio Avatar answered Dec 06 '22 09:12

Grzenio