2013-06-23 12 views
5

Come posso passare da un istante all'altro? Supponiamo di avere questa classe. Come passare da foo (stringa, stringa) a foo (Uri)?Concatenamento del concatenatore che passa valori calcolati per i parametri

public foo 
{ 
    string path { get; private set; } 
    string query { get; private set; } 

    public foo (Uri someUrl) 
    { 
     // ... do stuff here 
    } 

    public foo (string path, string query) 
    { 
     Uri someUrl = new Uri(String.Concat(path, query); 

     // ... do stuff here to pass thru to foo(someUrl) 
    } 
} 
+0

Votazione per riapertura. La risposta nel post duplicato è corretta ma è più orientata al parametro "semplice" che passa al costruttore successivo. Il post di OP suggerisce che ci sia dell'elaborazione da fare all'URI prima di trasmetterla. Una risposta più adatta sarebbe quella di avere un metodo comune che entrambi i costruttori chiamano e passano i parametri per riferimento. – keyboardP

+0

@keyboardP, d'accordo con te. Ho modificato il titolo per riflettere quello più precisamente e ho votato per riaprire. (anche cercato duplicati di questa sfumatura, e venne fuori vuoto) –

+0

Grazie per la riapertura. –

risposta

4

Si può anche fare qualcosa di simile:

class Frob 
{ 
    public Frob (Uri uri) 
    { 

    } 

    public Frob(string path, string query) 
     : this(TidyUpUri(path, query)) 
    { 

    } 

    private static Uri TidyUpUri(string path, string query) 
    { 
     var uri = new Uri(string.Concat(path, query)); 

     // etc. 

     return uri; 
    } 
} 
+0

Fantastico. Questa è la tecnica che ho finito per usare. Grazie! –

7

Per semplice concatenamento costruttore, è possibile utilizzare le parole chiave speciali this o base per riferirsi ad altri costruttori della classe corrente o genitore. È consentito utilizzare qualsiasi parametro per il costruttore di esecuzione come parametri per il costruttore concatenato e è possibile combinarli utilizzando qualsiasi espressione legale singola. Si tratta fondamentalmente delle stesse regole che si applicano a qualsiasi altra espressione inline fornita a una chiamata di funzione, eccetto che si dovrebbe evitare di utilizzare qualsiasi membro della classe (poiché non è ancora stato costruito) e limitarsi alle costanti e ai parametri pass-through:

public foo (Uri someUrl) 
{ 
    this.url = someUrl; 
} 

public foo (string path, string query) 
    : this(new Uri(String.Concat(path, query))) 
{ 
    // this.url is now set and available. 
} 

Ciò funzionerà finché l'elaborazione che è necessario eseguire può essere eseguita in un'unica espressione di valore. Se, ad esempio, avessi avuto bisogno di fare qualcos'altro con lo Uri prima di essere inviato all'altro costruttore, o se avessi bisogno di qualche complessa logica if/then, non saresti in grado di farla franca con questa tecnica. L'alternativa è quella di refactoring del codice in un metodo di inizializzazione:

public foo (Uri someUrl) 
{ 
    this.init(someUrl); 
} 

public foo (string path, string query) 
{ 
    var url = String.Concat(path, query); 
    url = url.Replace("http://", "https://"); 

    this.init(url); 
} 

private void init (Uri someUrl) 
{ 
    this.url = someUrl; 
} 
+1

Minor nitpick, ma probabilmente è meglio rendere privato 'init'. –

+0

Ho capito! Se ho requisiti di concatenazione più complessi, la prossima volta imposterò un init. Grazie! –

2

Dal momento che stai elaborazione le corde prima di passare loro lungo, è possibile estrarre a un metodo comune Per esempio

private void ProcessUri(ref Uri theUri) 
{ 
    //...do your URI stuff here 
} 

public foo (Uri someUrl) 
{ 
    ProcessUri(ref someUrl); 
} 

public foo (string path, string query) 
{ 
    Uri someUrl = new Uri(String.Concat(path, query)); 

    // ... do stuff here to pass then call ProcessUri 
    ProcessUri(ref someUrl); 
} 

Il vantaggio delle cose che passano con ref è che è possibile impostare i valori delle proprietà readonly proprio come si farebbe se la variabile è stata impostata all'interno del costruttore.

Problemi correlati