Domanda

In Visual Studio 2008 utilizzando C#, qual è il modo migliore per condividere codice tra più classi e file di origine?

L'ereditarietà non è la soluzione poiché le classi hanno già una gerarchia significativa.

Esiste qualche funzionalità interessante simile a un file di inclusione C che ti consente di inserire il codice ovunque desideri in un'altra classe?

MODIFICARE:

ok, immagino che serva un esempio concreto...

Esistono diverse centinaia di classi nel dominio con una gerarchia di classi ben congegnata.Ora, molte di queste classi devono essere stampate.Esiste una classe stampante di utilità che gestisce la stampa.Diciamo che ci sono 3 diversi metodi di stampa che dipendono dalla classe che viene stampata.Il codice che chiama il metodo print (6 righe) è quello che sto cercando di evitare di copiare e incollare su tutte le diverse pagine della classe client.

Sarebbe bello se le persone non dessero per scontato di saperne di più sul dominio che sull'operazione, specialmente quando menzionano specificamente tecniche che non si adattano...

È stato utile?

Soluzione

Se si dispone di funzionalità che si utilizzano spesso in classi che rappresentano cose molto diverse, nella mia esperienza che dovrebbe cadere in poche categorie:

  • Utilità (ad esempio formattazione di stringhe, analisi, ...)
  • preoccupazioni
  • trasversali (logging, l'applicazione di sicurezza, ...)

Per la funzionalità di utilità-tipo si dovrebbe considerare la creazione di classi separate, e fa riferimento alle classi di utilità in funzione delle esigenze della business class.

public class Validator
{
  public bool IsValidName(string name);
}

class Patient
{
  private Validator validator = new Validator();
  public string FirstName
  {
     set
     {
         if (validator.IsValidName(value)) ... else ...
     }
  }
}

Per preoccupazioni trasversali come la registrazione o la sicurezza, vi consiglio di indagare Aspect-Oriented Programming .

Per quanto riguarda l'esempio Printa vs. PrintB discusso in altri commenti, suona come un caso eccellente per il modello di fabbrica. Si definisce un'interfaccia per esempio IPrint, classi Printa e PrintB che implementano entrambi IPrint, e assegnare un'istanza di IPrint base a quanto le particolari esigenze di pagina.

// Simplified example to explain:

public interface IPrint 
{ 
   public void Print(string); 
}

public class PrintA : IPrint
{
   public void Print(string input)
   { ... format as desired for A ... }
}

public class PrintB : IPrint
{
   public void Print(string input)
   { ... format as desired for B ... }
}

class MyPage
{
   IPrint printer;

   public class MyPage(bool usePrintA)
   {
      if (usePrintA) printer = new PrintA(); else printer = new PrintB();
   }

   public PrintThePage()
   {
      printer.Print(thePageText);
   }
}

Altri suggerimenti

Non puoi semplicemente caricare il codice che vorresti aggiungere in una classe in C# tramite una direttiva del preprocessore come faresti in C.

Potresti, tuttavia, definire un'interfaccia e dichiarare metodi di estensione per quell'interfaccia.L'interfaccia potrebbe quindi essere implementata dalle tue classi e puoi chiamare i metodi di estensione su quelle classi.Per esempio.

public interface IShareFunctionality { }

public static class Extensions
{
    public static bool DoSomething(this IShareFunctionality input)
    {
        return input == null;
    }
}

public class MyClass : Object, IShareFunctionality
{
    public void SomeMethod()
    {
        if(this.DoSomething())
            throw new Exception("Impossible!");
    }
}

Ciò ti consentirebbe di riutilizzare la funzionalità, ma non puoi accedere ai membri privati ​​della classe come potresti fare se potessi, ad esempio, includere un file con l'hash.

Tuttavia, potremmo aver bisogno di alcuni esempi più concreti di ciò che vuoi fare?

A C # utility della classe funzionerà. Si comporta come un registro centrale per il codice comune (o come il modulo costrutto VB.NET) - dovrebbe contenere codice che non è specifico per ogni classe in caso contrario avrebbe dovuto essere collegata alla relativa classe.

Non desidera iniziare la copia del codice sorgente in giro se non si dispone di perché questo porterebbe a problemi di aggiornamento del codice considerando il duplicazione .

Finché la fonte non ha bisogno di mantenere lo stato, quindi utilizzare una classe statica con metodo statico.

static public class MySharedMembers {
    static public string ConvertToInvariantCase(string str)  {
        //...logic
    }
    // .... other members
}

Se le classi sono nello stesso spazio dei nomi, non c'è bisogno di un analogo includere. Basta chiamare i membri della classe definita in altra funzione.

Se non sono nello stesso spazio dei nomi, aggiungere lo spazio dei nomi delle classi che si desidera utilizzare nelle direttive usings e dovrebbe funzionare lo stesso come sopra.

Sono confuso dalla domanda: sembra è necessario lavorare sulla vostra conoscenza di base OO

.

Non so di un modo per includere porzioni di file, ma una cosa che facciamo di frequente è quello di aggiungere un file esistente e "link" dalla sua posizione corrente. Per esempio, abbiamo un file AssemblyInfo.cs che ogni progetto si riferisce a da una directory soluzione. Abbiamo cambiare una volta e tutti i progetti hanno le stesse informazioni, perché stanno facendo riferimento allo stesso file.

In caso contrario, i suggerimenti circa il refactoring routine "comuni" in un common.dll sono la cosa migliore che è venuta in mente in .Net.

Non sono sicuro esattamente cosa si intende per una struttura "significativo" già, ma questo suona come un luogo dove si poteva usare implementazione della classe base. Anche se non così "verbose", come C ++ l'ereditarietà multipla, si potrebbe ottenere qualche beneficio da utilizzare implementazione della classe base incatenato a riutilizzare funzioni comuni.

È possibile conservare gerarchia di classe, almeno visivamente e ignorare il comportamento a seconda delle necessità.

Estrarre il codice ripetitivo in servizi. Il codice ripetitivo è un indizio che ci possa essere spazio per il refactoring.

Ad esempio, creare un "PrintingService", che contiene la logica necessaria per stampare. È quindi possibile avere le classi che hanno bisogno di stampare avere una dipendenza da questo servizio (sia tramite il costruttore o un parametro in un metodo che richiede il servizio).

Un'altra punta ho lungo queste linee è di creare interfacce per funzionalità di base e quindi utilizzare le interfacce per codificare contro. Per esempio, ho avuto gruppo di classi di report che l'utente potrebbe o fax, e-mail, o stampare. Invece di creare metodi per ogni, ho creato un servizio per ciascuna, li aveva implementano un'interfaccia che aveva un unico metodo di uscita (). Potrei quindi passare ogni servizio per lo stesso metodo a seconda del tipo di prodotto che l'utente voleva. Quando il cliente voleva utilizzare eFax invece di fax tramite il modem, era solo una questione di scrivere un nuovo servizio che ha implementato questa stessa interfaccia.

Per essere onesti non riesco a pensare a una cosa del genere comprende in Visual C #, né perché si vorrebbe che la funzione. Detto questo, le classi parziali possono fare qualcosa di simile suona ciò che si vuole, ma il loro utilizzo forse si scontra contro la vostra "classi hanno già una gerarchia di significato" requisito.

Avete molte opzioni, TT, metodo di estensione, delegato, e lambda

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top