Ayuda C#. Usar objeto instanciado en un clase, en otra clase

Hola a todo. Gracias por leer.
Les cuento el problema. Tengo dos clases, en una de ellas instancio un objeto Socket, mediante el cual hago una conexion a una PC. Y en otra clase me gustaria usar exactamente el mismo objeto socket para enviar datos a la PC, sin tener que instanciar uno nuevo. Como puedo hacerlo?

En esta clase, esta el main, y es en la cual instancio el objeto socket, el cual tambien quiero utilizar en la clase de mas abajo, llamada logger.
Código:
namespace Client
{
    public class Program
    {
        public static void Main(string[] args)
        {
   
            IPAddress direc = Dns.GetHostEntry("host.dyndns.org").AddressList[0];
            IPEndPoint Ep = new IPEndPoint(direc, 12345);
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);

            while (!socket.Connected)
            {
                try
                {
                    socket.Connect(Ep);
                }
                catch
                {
                }
            }

           Console.WriteLine("Conexion con server ("+Ep.ToString()+") satisfactoria");
        }
    }
}

clase logger
Código:
namespace Client
{
   public class logger
    {
        socket.send(Encoding.ASCII.GetBytes("hola")); // esto es lo que pretendo hacer y no puedo
     }
}
 
Última edición:
Gonzalo, poder se puede. No recuerdo bien cómo, pero lo que yo hice fué crear una clase Cliente (por ejemplo) y cuando tenía que hacer algo con ese objeto pues tenía que instar la Clase y luego el objeto, esto es; Cliente.Socket.

Pero como digo no recuerdo bien.
 
Solo hay dos formas de hacerlo: Una buena y una pésima.
La buena: crear una clase pública que opere según el patrón de diseño Singleton y que permita acceder a la instancia del socket a quien se la pida ===> Estudiar patron de diseño Singleton, que permite muchas cosas útiles adicionales.
La pésima: Hacer pública la referencia a la instancia del socket y accederlo desde cualquier parte prefijándolo con el nombre de la instancia de la clase que lo contiene, o con el nombre de la clase si es referencia estática ===> ver y descifrar lo que te dice Pelelalo
 
La pésima: Hacer pública la referencia a la instancia del socket y accederlo desde cualquier parte prefijándolo con el nombre de la instancia de la clase que lo contiene, o con el nombre de la clase si es referencia estática ===> ver y descifrar lo que te dice Pelelalo

Supongo que te refieres a la seguridad.
 
Me alegro que les sea útil!
Este es un problema permanente que vengo viendo hace tiempo: se les enseña a programar usando un lenguaje O.O. y nunca se enseñan las miles de técnicas que han desarrollado y documentado los verdaderos especialistas del tema...y esas miles de técnicas están expuestas en los Patrones de Diseño. La conclusión es que siempre tienen que reinventar la rueda...SIEMPRE :enfadado:
Por desgracia, a esto solo pueden enseñarlo aquellos docentes que han usado los P. de D. en aplicaciones reales, por que no se aprenden con solo leerlos en un libro...y parece que no hay muchos de estos :eek:

En la web debe estar el libro de Gamma y colaboradores...búsquenlo, bájenlo y páguenlo :D y aprendan un montón de cosas super útiles, probadas, documentadas y desarrolladas por quienes saben mucho de esto...y también Microsoft :LOL: :LOL:

PD: Si consiguen Patterns in Java, de Mark Grand (son dos volúmenes) les va a ser bastante útil, por que tiene un enfoque bastante pediátrico y con mucho apoyo de UML.

Saludos!

Supongo que te refieres a la seguridad.
Me refiero a las bases del paradigma de la Orientación a Objetos: Encapsulación (esta es la que se está violando), Herencia y Polimorfismo (y estas últimas no vienen al caso).
Violar la encapsulación tiene como efecto colateral reducir la "seguridad" en la gestión del código. Hay formas de violar la Encapsulación de manera "segura", pero como pocos saben como se hace...y eso no quita que se la esté violando....es mejor no aplicarla.
 
Última edición:
Me refiero a las bases del paradigma de la Orientación a Objetos: Encapsulación (esta es la que se está violando), Herencia y Polimorfismo (y estas últimas no vienen al caso).
Violar la encapsulación tiene como efecto colateral reducir la "seguridad" en la gestión del código. Hay formas de violar la Encapsulación de manera "segura", pero como pocos saben como se hace...y eso no quita que se la esté violando....es mejor no aplicarla.

Como ya te dijeron, gracias por tu gran aporte.
 
Bueno, estuve investigando sobre Singleton, y sirve precisamente para lo que requiero.
Cito a Wikipedia:
"El patrón de diseño singleton (instancia única) está diseñado para restringir la creación de objetos pertenecientes a una clase o el valor de un tipo a un único objeto.
Su intención consiste en garantizar que una clase sólo tenga una instancia y proporcionar un punto de acceso global a ella"

El problema es que no se como implementarlo, soy realmente nuevo en C# pero tengo idea de programacion. Alguien me puede mostrar mas o menos como seria, con algun ejemplo super basico?
Gracias
 
Como ya leiste en wikipedia lo que se hace es privatizar al constructor para que la clase no pueda ser creada por metodos convencionales, despues crear un metodo publico que al llamarlo revise si la clase ya esta creada y genere un error si se requiere

Código:
public class Singleton
{
    // Variable estática para la instancia, se necesita utilizar una función lambda ya que el constructor es privado
    private static readonly Lazy<Singleton> instance = new Lazy<Singleton>(() => new Singleton());
 
    // Constructor privado para evitar la instanciación directa
    private Singleton()
    {
    }
 
    // Propiedad para acceder a la instancia
    public static Singleton Instance
    {
        get
        {
            return instance.Value;
        }
    }
}
 
// Clase de prueba
public class Prueba
{
   private static void Main(string[] args)
   {
     //Singleton s0 = new Singleton();  //Error
     Singleton s1 = Singleton.Instance;
     Singleton s2 = Singleton.Instance;
     if(s1==s2)
     {
       // Misma instancia
     }
   }
}

Lamentablemente de C# no se mucho... lo ando aplicando en PHP5
 
Gracias Chico3001. Mas o menos entiendo de que se trata. El tema es que la clase Socket no la hice yo.
Forma parte de "System.Net.Sockets". Es por eso que no puedo modificar sus contructores.
Yo simplemente quiero utilizar el socket instanciado en la clase "program", en la clase "logger" y no entiendo como implementar Singleton aplicado a esto. Muchas gracias y saludos
 
Te lo paso en Java...vos adaptalo a C#.
Código:
public class Singleton {

   private static Socket skt = null;

   private Singleton() {  /* Nada */  }

   public static Socket getSocket() {
      if( skt == null ) {
      // inicializar el socket
      }
      return skt;
   }

}
Es importante que la variable skt y el metodo getSocket sean de clase y no de instancia para asegurar la existencia de un solo socket.
Esto solo es un ejemplo y NO ES la mejor forma de hacerlo...pero bueno...se entiende la idea.

Ooopppssss...ya contestó Chico3001...eso me pasa por dejar lo compu sin terminar lo que estoy haciendo....
 
Última edición:
Creo que termine de entender (duro el chico). De esta forma en cada clase que quiera usar el socket primero lo tengo que instanciar antes, y en lugar de crearse un objeto socket nuevo, se utiliza el creado en Singleton, correcto?. Les muestro el codigo a ver si lo aprueban o me sugieren algun cambio. Por el momento funciona.

Clase Singleton
Código:
namespace Client
{
    public class Singleton
    {
   
        private static Socket skt = null;

        private Singleton() {}

        public static Socket getSocket()
        {
            if (skt == null)
            {
                IPAddress direc = Dns.GetHostEntry("host.dyndns.org").AddressList[0];
                IPEndPoint Ep = new IPEndPoint(direc, 12345);
                skt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);

                 while (!skt.Connected)
                {
                    try
                    {
                        skt.Connect(Ep);
                    }
                    catch
                    {
                    }
                
                }
                Console.WriteLine("Conexion con server ("+Ep.ToString()+") satisfactoria");
            }
            return skt;
        }
    }
}

Clase Program

Código:
namespace Client
{
    class Program
    {
     public static void Main(string[] args)
        {
            Socket skt = Singleton.getSocket();
            
   
            string strDataIn = "Hola!!\n";
            byte[] clientData = new byte[1024];

            clientData = Encoding.ASCII.GetBytes(strDataIn);

            skt.Send(clientData);

            skt.Close(); //[B][COLOR="Red"]Se cierra el socket por completo? o solo en esta clase? Gracias![/COLOR][/B]
            
        }
     }
}

Les agradesco mucho, funiona barbaro. Saludos!
 
Última edición:
Si cerrás el socket, como es el único que hay, se cierra para todos. Por eso te dije que no era la mejor forma de hacerlo....por que en realidad habría que aplicar un patrón Decorator para esconder el acceso al socket puro....pero eso requiere seguir estudiando.
 
Gracias ezavalla. Me pasarias el nombre del libro de Gamma que mencionaste unos posts atras. Como lo ves para aprender C# teniendo medios conocimientos de c++?
Saludos y gracias
 
El libro de Gamma y colaboradores se llama "Design Patterns: Elements of Reusable Object-Oriented Software" y está escrito para C++... nada que ver con C#
 
Atrás
Arriba