Hi all, I'm pretty new to C#, but I've been trying to figure out the logic behind my problem for a couple of days now.
The documentation I've read all makes sense, but I can't find anything about this particular circumstance/problem that I can identify.
And actually, I'm not even sure what this sort of conversion technique is called, but it seems like an explicit conversion of a base class to a derived class of that base class... anyway, it doesn't work and I'm stumped, but I know I'm missing something really simple.
using System;
using System.Net;
using System.Net.Sockets;
namespace CastingTest {
class NewSocketClass : Socket {
string selfName;
public NewSocketClass( AddressFamily af, SocketType st, ProtocolType pt ) : base( af, st, pt ) {
selfName = "Generic";
Console.WriteLine( "{0} constructed.", selfName );
}
public NewSocketClass( AddressFamily af, SocketType st, ProtocolType pt, string name ) : base( af, st, pt ) {
selfName = name;
Console.WriteLine( "{0} constructed.", selfName );
}
public void HelloWorld() {
Console.WriteLine( "Hello, {0}!", selfName );
}
}
class CastMain {
public static void Main() {
NewSocketClass s = new NewSocketClass( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, "Listener" );
s.Bind( new IPEndPoint( IPAddress.Loopback, 8090 ) );
s.Listen( 10 );
s.HelloWorld();
NewSocketClass i = (NewSocketClass)s.Accept(); <-- Error: Cannot cast from source type to destination type.
i.HelloWorld();
}
}
}
--
I should mention I've also tried simply declaring operator handlers for the conversions, and avoiding the derive altogether:
using System;
using System.Net;
using System.Net.Sockets;
namespace CastingTest {
class NewSocketClass {
string selfName;
Socket sock = null;
public NewSocketClass( Socket s ) : this( s.AddressFamily, s.SocketType, s.ProtocolType ) {
this.sock = s;
}
public NewSocketClass( AddressFamily af, SocketType st, ProtocolType pt ) {
selfName = "Generic";
if( this.sock == null )
this.sock = new Socket( af, st, pt );
Console.WriteLine( "{0} constructed.", selfName );
}
public NewSocketClass( AddressFamily af, SocketType st, ProtocolType pt, string name ) : this( af, st, pt ) {
selfName = name;
Console.WriteLine( "{0} constructed.", selfName );
}
public static implicit operator Socket( NewSocketClass rvalue ) {
return rvalue.sock;
}
public static implicit operator NewSocketClass( Socket rvalue ) {
return new NewSocketClass( rvalue );
}
public void HelloWorld() {
Console.WriteLine( "Hello, {0}!", selfName );
}
}
class CastMain {
public static void Main() {
NewSocketClass s = new NewSocketClass( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, "Listener" );
((Socket)s).Bind( new IPEndPoint( IPAddress.Loopback, 8090 ) );
((Socket)s).Listen( 10 );
s.HelloWorld();
NewSocketClass i = (NewSocketClass)((Socket)s).Accept();
i.HelloWorld();
}
}
}
And this all works great, until I attempt to select on the resulting sockets, which results in:
Unhandled Exception: System.InvalidCastException: Cannot cast from source type to destination type.
at System.Net.Sockets.Socket.AddSockets (System.Collections.ArrayList sockets, IList list, System.String name) [0x00000]
at System.Net.Sockets.Socket.Select (IList checkRead, IList checkWrite, IList checkError, Int32 microSeconds) [0x00000]
and a clearer version (from MS.Net):
Unhandled Exception: System.ArgumentException: The operation is not allowed on objects of type Valstream.VSListener. Use only objects of type System.Net.Sockets.Socket.
Parameter name: socketList
at System.Net.Sockets.Socket.SocketListToFileDescriptorSet(IList socketList)
at System.Net.Sockets.Socket.Select(IList checkRead, IList checkWrite, IList checkError, Int32 microSeconds)
at Valstream.VSMain.mainLoop()
at Valstream.VSMain.Main()