Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 19
  1. #1

    [C#] Due classi, un richiamo

    Salve a tutti,
    durante la scrittura di un programma è apparso un nuovo problema che non riesco a risolvere: ho due classi più una base. Le due classi contengono delle funzioni per accedere a due differenti tipi di database, access e mysql. Non sapendo con esattezza al momento del richiamo della classe quale database sto usando vorrei lasciar decidere alla classe base quale richiamare tra le due... è fattibile? se si come?

  2. #2
    Non riesci a portare l'esecuzione del tuo programma in una situazione simile a questa?

    Codice PHP:
    using System;

    namespace 
    Application
    {
        public interface 
    IDb
        
    {
            
    void connect();
            
    void exec();
        }
        
        public class 
    MySQL IDb
        
    {
            public 
    MySQL(){}
            public 
    void connect(){ Console.WriteLine("MySQL.connect"); }
            public 
    void exec(){ Console.WriteLine("MySQL.exec"); }
        }
        
        public class 
    Access IDb
        
    {
            public 
    Access(){}
            public 
    void connect(){ Console.WriteLine("Access.connect"); }
            public 
    void exec(){ Console.WriteLine("Access.exec"); }
        }
        
        public class 
    Test
        
    {    
            public static 
    void f(IDb db)
            {
                
    db.connect();
                
    db.exec();
            }
            
            public static 
    void Main()
            {
                
    MySQL a = new MySQL();
                
    Access b = new Access();
                
                
    f(a);
                
    f(b);
            }
        }


  3. #3
    è più o meno così il programma, ma il vero problema sta nel fatto che dovrei richiamare la classe MySql o Access a seconda del database che uso poichè contengono le stesse funzioni ma scritte appunto per essere compatibili con il DB scelto e non vorrei ogni volta fare una if per verificare il tipo di database in uso. L'idea mia se fattibile era istanziare la classe base la quale carica la classe giusta

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328

    Moderazione

    C# = Linguaggio .NET. = forum "Visual Basic e .NET Framework".

    Sposto.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Non ho ben capito perchè, durante l'esecuzione, non hai possibilità di conoscere il database che utilizzi e quindi utilizzare il polimorfismo. Solitamente il database da utilizzare viene passato come parametro, da file di configurazione, da radio button o simili, che ti danno la possibilità di saperlo.
    Potresti spiegare meglio la situazione? Magari basta un ritocco alla fase di progettazione.

    Se dovessi fa scegliere alla classe base il db da utilizzare, penso che non ne vieni fuori senza una serie di if, che sarebbero ovviamente sintomo di cattiva programmazione:

    Codice PHP:
    using System

    namespace 
    Application 

        public interface 
    IDb 
        

            
    void connect(); 
            
    void exec(); 
        } 
         
        public class 
    MySQL IDb 
        

            public 
    MySQL(){} 
            public 
    void connect(){ Console.WriteLine("MySQL.connect"); } 
            public 
    void exec(){ Console.WriteLine("MySQL.exec"); } 
        } 
         
        public class 
    Access IDb 
        

            public 
    Access(){} 
            public 
    void connect(){ Console.WriteLine("Access.connect"); } 
            public 
    void exec(){ Console.WriteLine("Access.exec"); } 
        } 

        public 
    enum DbNameMySQLAccess };

        public class 
    MyDbClass
        
    {
            public 
    MyDbClass(DbName name)
            { 
                
    setDb(name);
            }

            public 
    void setDb(DbName name)
            {
                if(
    name == DbName.MySQL)
                    
    db = new MySQL();
                else if(
    name == DbName.Access)
                    
    db = new Access();
            }

            public 
    void connect(){ db.connect(); }
            public 
    void exec(){ db.exec(); }

            private 
    IDb db;
        }
         
        public class 
    Test 
        
    {     
            public static 
    void f(MyDbClass db
            { 
                
    db.connect(); 
                
    db.exec(); 
            } 
             
            public static 
    void Main() 
            { 
                
    MyDbClass a = new MyDbClass(DbName.MySQL);   
                
    MyDbClass b = new MyDbClass(DbName.Access);
                 
                
    f(a); 
                
    f(b);

                
    a.setDb(DbName.Access);
                
    f(a);
            } 
        } 


  6. #6
    bè, siccome vorrei supportare eventuali estensioni future del programma per adattarsi ad altri databases e non solo mysql e access per esempio, sarebbe seccante definire ad ogni operazione o file un new MySql/Access e dopo fare le if per chiamare la classe giusta ogni volta che devo chiamare una funzione

  7. #7
    bè, siccome vorrei supportare eventuali estensioni future del programma per adattarsi ad altri databases e non solo mysql e access per esempio, sarebbe seccante definire ad ogni operazione o file un new MySql/Access e dopo fare le if per chiamare la classe giusta ogni volta che devo chiamare una funzione
    Beh è ovvio che, l'introduzione della gestione di un nuovo database comporta la modifica di una parte del programma. Seguendo l'OP principle, però, dovresti metter mano al corpo del programma e non alle classi che lo fanno funzionare.
    Nel primo esempio, quello che ti ho consigliato, avevi un'interfaccia e due classi che la implementavano. La funzione f lavora un un oggetto IDb, qualunque esso sia.
    A questo punto ti accorgi che, l'interfaccia non la modifichi, le classi derivate non le modifichi e la funzione che effettivamente svolte il lavoro non la modifichi.
    Resta però che l'introduzioni di nuove classi derivate dall'interfaccia è ammessa senza problemi, dunque l'estensione del programma non ne risente in nessun modo.
    Rimane solo da modificare il main del programma. A esempio, considerando un'applicazione con gui:

    codice:
    class Postgres : IDb{...}
    
    function radiobuttonMysql.click():
      oggettoApplicazione.db = new MySQL();
    
    function radioButtonPostgres.click():
      oggettoApplicazione.db = new Postgres();
    
    /*
    ...
    */
    
    // supponiamo che in oggettoApplicazione.db ora ci sia 
    // un oggetto Postgres
    f(oggettoApplicazione.db); // la f dell'altro esempio
    anche qui, ad esempio, noti come i gestori di eventi non vengano toccati. Se aggiungi un nuovo radiobutton per gestire un nuovo database, aggiungi semplicemente un nuovo evento e istanzi la giusta classe per il db. Nient'altro viene modificato.

    Per questo ti consiglio di sfruttare le interfacce e tutto quello che ne segue. Gli if in questa soluzione non sono neanche contemplati


  8. #8
    grazie mille, la tua soluzione sembra essere adattissima alle mie esigenze. Solo una cosa: è assolutamente necessario ripetere due volte il richiamo alle funzioni sia all'interno della classe base che all'interno dell'interfaccia?

  9. #9
    Aspetta, credo tu stia considerando l'esempio che ti ho introdotto come inadatto.
    L'esempio corretto è questo:

    Codice PHP:
    using System

    namespace 
    Application 

        public interface 
    IDb 
        

            
    void connect(); 
            
    void exec(); 
        } 
         
        public class 
    MySQL IDb 
        

            public 
    MySQL(){} 
            public 
    void connect(){ Console.WriteLine("MySQL.connect"); } 
            public 
    void exec(){ Console.WriteLine("MySQL.exec"); } 
        } 
         
        public class 
    Access IDb 
        

            public 
    Access(){} 
            public 
    void connect(){ Console.WriteLine("Access.connect"); } 
            public 
    void exec(){ Console.WriteLine("Access.exec"); } 
        } 
         
        public class 
    Test 
        
    {     
            public static 
    void f(IDb db
            { 
                
    db.connect(); 
                
    db.exec(); 
            } 
             
            public static 
    void Main() 
            { 
                
    MySQL a = new MySQL(); 
                
    Access b = new Access(); 
                 
                
    f(a); 
                
    f(b); 
            } 
        } 

    Dove non hai una classe base. Hai tante classi quanti sono i db che devi gestire.
    Ad esempio, supponiamo che la classe principale Test abbia un attributo dbhandler e ci siano due tasti e due relativi event handler (non ho visual studio davanti e non ricordo molto bene l'argomento event, quindi utilizzo pseudocodice):

    Codice PHP:
    using System

    namespace 
    Application 

        public interface 
    IDb 
        

            
    void connect(); 
            
    void exec(); 
        } 
         
        public class 
    MySQL IDb 
        

            public 
    MySQL(){} 
            public 
    void connect(){ Console.WriteLine("MySQL.connect"); } 
            public 
    void exec(){ Console.WriteLine("MySQL.exec"); } 
        } 
         
        public class 
    Access IDb 
        

            public 
    Access(){} 
            public 
    void connect(){ Console.WriteLine("Access.connect"); } 
            public 
    void exec(){ Console.WriteLine("Access.exec"); } 
        } 
         
        public class 
    Postgres IDb 
        

            public 
    Postgres(){} 
            public 
    void connect(){ Console.WriteLine("Postgres.connect"); } 
            public 
    void exec(){ Console.WriteLine("Postgres.exec"); } 
        }

        public class 
    Test 
        
    {     
            private 
    IDb dbhandler;

            public static 
    void f(IDb db
            { 
                
    db.connect(); 
                
    db.exec(); 
            } 
             
            public static 
    void Main() 
            { 
                
    init();
                
    buttonMySQL.clickeventhandler += btnMySQL.EventHandler();
                
    buttonAccess.clickeventhandler += btnAccess.EventHandler();
                
    buttonPostgres.clickeventhandler += btnPostgres.EventHandler();

                
    buttonExec.clickeventhandler += btnExec.EventHandler();
            } 

            
    btnMySQL.EventHandler()
            {
                
    dbhandler = new MySQL();
            }

            
    btnAccess.EventHandler()
            {
                
    dbhandler = new Access();
            }

            
    btnPostgres.EventHandler()
            {
                
    dbhandler= new Postgres();
            }

            
    btnExec.EventHandler()
            {
                
    f(dbhandler);
            }

        } 


  10. #10
    no aspetta, continuo a fare un sacco di confusione. Si può fare in modo che chiamando una classe base o un'interfaccia e passando quindi il tipo di database automaticamente venga restituito un oggetto alla classe del database scelto dal parametro?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.