2013-04-03 15 views
5

È pratica accettabile passare un oggetto in un metodo, quindi restituire lo stesso oggetto anziché creare un nuovo oggetto all'interno del metodo stesso?metodo restituisce lo stesso oggetto passato come parametro

Per fare un esempio: se abbia una classe di entità come segue:

class UserDetails { 
    int UserID { get; set; } 
    string UserName { get; set; } 
    string UserAge { get; set; } 
} 

E poi mi passa un'istanza di questa classe a un metodo, come segue:

UserDetails UserInfo = new UserDetails(); 
UserInfo = Get_Details(UserInfo); 

E 'ragionevole per il metodo per fare quanto segue?

public UserDetails Get_Details(UserDetails user) { 
    // SQL Operations... 
    user.age = 32; 
    return user; 
} 
+3

Un'osservazione, si sta impostando i dettagli, invece di far loro :-p –

+2

una piccola cosa: il tuo nome della funzione è fuorviante (non vorrei immaginare che una funzione denominata 'Get_Details' cambia il suo ingresso). altro poi che la pratica che si illustra è corretta. – Oren

+1

Forse dovrebbe essere lo scambio dello stack di revisione del codice? – James

risposta

1

Questo può essere utile con il builder pattern (quando si vuole costruire un passo oggetto complesso per passo).

Come un pessimo esempio:

class FooBuilder { 
    FooBuilder WithAge(int age); 
    FooBuilder WithUrl(Url url); 

    Foo ToFoo(); 
} 

new FooBuilder().WithAge(12).WithUrl(new Url("http://www.happybirthday.com/").ToFoo(); 

Nel vostro caso particolare, preferisco inizializzare tutto in un colpo solo con la sintassi di inizializzazione.

new User { Age = 45, UserName = "Bob", Id = 101 }; 
0

Questo è un approccio possibile e quando si dispone di un solo articolo a lavorare uno, il migliore, anche. Si potrebbe anche prendere in considerazione di utilizzare ref, che crea un riferimento al parametro passato

public void Get_Details(ref UserDetails user) 
{ 
    // SQL Operations. . . 
    user.age= 32; 
} 

in questo modo, non si passa una copia, ma fare riferimento all'oggetto che avete passato. Ma questo può diventare molto oscuro e è non necessario nel tuo caso. Vedi here per un approfondimento.

+1

Utilizzerai la parola chiave ref solo se desideri modificare il riferimento reale. Passando senza la parola chiave 'ref' non si crea una copia dell'oggetto, ma si crea solo una copia del riferimento. – Guffa

+0

Questo non ha senso ... Perché c'è "ref" allora? –

+0

La parola chiave 'ref' crea un riferimento alla variabile che contiene il riferimento (o la variabile che contiene il valore se è un tipo di valore). È possibile modificare la variabile che viene passata dall'interno del metodo. – Guffa

0

Si potrebbe fare bene a cercare i concetti del modello di deposito e OOD. In generale, preferisco le proiezioni o le entità completamente caricate.

public UserDetailsProjection GetDetailsByUserId(Guid userID) 
{ 
    // Code goes here 
    return user; 
} 

Nota: non è necessario, perché tutti gli oggetti vengono passati per riferimento.

2

IMO, non è necessario restituire l'oggetto. Dal è passato al metodo tramite il riferimento, il chiamante ha già un riferimento allo stesso oggetto (con i valori aggiornati dopo il completamento del metodo).

D'altra parte, ciò che può essere utile in alcune situazioni è una fluente interfaccia, dove istanza-metodi di una classe ritornano nuovamente l'istanza, ad esempio:

class X 
{ 
    public X DoThis(int number) 
    { 
    // do something 
    return this; 
    } 
    public X DoThat(string name) 
    { 
    // do something else 
    return this; 
    } 
} 

Questo permette di scrivere codice molto leggibile , come ad esempio:

var x = new X().DoThis(23).DoThat("asdf"); 
0

farlo del genere è piuttosto inutile, in quanto l'assegnazione che si fa non cambia nulla.

chiamata in questo modo:

UserInfo = Get_Details(UserInfo); 

dà lo stesso risultato chiamandolo e ignorando il valore di ritorno:

Get_Details(UserInfo); 

Tornando il riferimento può essere solo fonte di confusione, che porta qualcuno a credere che il metodo restituisce una nuova istanza, in quanto sarebbe l'unico motivo logico per restituire un riferimento.

Avrebbe più senso avere quel metodo nella classe, in modo che si chiama come:

UserInfo.Get_Details(); 

Se si suppone che il metodo per inizializzare l'oggetto, si preferisce mettere il codice che il costruttore di chiamarlo dopo aver creato l'istanza:

class UserDetails { 

    int UserID { get; set; } 
    string UserName { get; set; } 
    string UserAge { get; set; } 

    public UserDetails() { 
    Get_Details(this); 
    } 

} 

Poi basta creare l'istanza, e il costruttore carica i dati:

UserDetails UserInfo = new UserDetails(); 
1

Non c'è nulla di terribilmente sbagliato in questo, ma un paio di osservazioni;

  • Si sta impostando i dettagli all'interno di un metodo chiamato get forse load è più appropriato.
  • Se si passa solo in UserDetails perché si desidera l'id per il proprio, il parametro dovrebbe essere solo id. Ciò mantiene l'interfaccia coesa.
  • Generalmente è considerata una cattiva forma modificare un oggetto parametro all'interno di un metodo, cioè il principio di mutazione.
0

È possibile riempire la propria entità nel suo metodo di costruzione o in un altro metodo all'interno della classe di entità. Sarà pronto per l'uso al momento della creazione.

public class SomeClass 
{ 
    public string Field_1; 
    public int Field_2; 

    public SomeClass(int ID) 
    { 
     // Sql operations by ID or another value 
     // set fields 
    } 

    public AnotherMethod(int ID) 
    { 
     // Sql operations by ID or another value 
     // set fields 
    } 
} 
Problemi correlati