10

Is it acceptable practice to pass an object into a method, then return the same object rather than creating a new object inside of the method itself?

As an example: if have an entity class as follows:

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

And then I pass an instance of this class to a method, as follows:

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

Is it reasonable for the method to do the following?

public UserDetails Get_Details(UserDetails user) {
    // SQL Operations...
    user.age = 32;
    return user;
}
Troy Alford
  • 26,660
  • 10
  • 64
  • 82
punter
  • 460
  • 1
  • 6
  • 22

7 Answers7

4

IMO, there is no need to return the object. Since it is passed to the method by reference, the caller already has a reference to the same object (with the updated values after the method completes).

On the other hand, what can be useful in some situations is a fluent-interface, where instance-methods of a class return the instance again, e.g:

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

This allows to write very readable code, such as:

var x = new X().DoThis(23).DoThat("asdf");
M4N
  • 94,805
  • 45
  • 217
  • 260
1

This can be useful with the builder pattern (when you want to build a complex object step by step).

As a very bad example:

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

  Foo ToFoo();
}

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

In your particular case, I'd prefer to initialize everything in one go with the initializer syntax.

new User { Age = 45, UserName = "Bob", Id = 101 };
Jeff Foster
  • 43,770
  • 11
  • 86
  • 103
1

Doing it like that is rather pointless, as the assignment that you do doesn't change anything.

Calling it like this:

UserInfo = Get_Details(UserInfo);

gives the same result as calling it and ignoring the return value:

Get_Details(UserInfo);

Returning the reference may only be confusing, leading someone to believe that the method returns a new instance, as that would be the only logical reason to return a reference.

It would make more sense to have that method in the class, so that you call it as:

UserInfo.Get_Details();

If your method is supposed to initialise the object, you would rather put the code it the constructor than calling it after creating the instance:

class UserDetails {

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

  public UserDetails() {
    Get_Details(this);
  }

}

Then you just create the instance, and the constructor loads the data:

UserDetails UserInfo = new UserDetails();
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
1

There is nothing horribly wrong with this but a couple of observations;

  • You are setting details inside of a method called get perhaps load is more appropriate.
  • If you are only passing in UserDetails because you want the id for your then the parameter should just be id instead. This keeps the interface cohesive.
  • It is generally considered bad form to modify a parameter object within a method, i.e., mutation principle.
James
  • 1,541
  • 12
  • 25
0

This is a possible approach and when you have only ONE item to work one, the best, too. You might also consider to use ref, which creates a reference to the passed parameter

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

this way, you don't pass a copy, but reference the object you passed in. But this can become quite obscure and is unnecessary in your case. See here for an insight.

Community
  • 1
  • 1
bash.d
  • 13,029
  • 3
  • 29
  • 42
  • 1
    You would only use the `ref` keyword if you want to change the actual reference. Passing it without the `ref` keyword doesn't create a copy of the object, it only creates a copy of the reference. – Guffa Apr 03 '13 at 07:59
  • This doesn't make sense... Why is there `ref` then? – bash.d Apr 03 '13 at 08:06
  • The `ref` keyword creates a reference to the variable holding the reference (or the variable holding the value if it is a value type). You can change the variable that is passed in from inside the method. – Guffa Apr 03 '13 at 08:09
  • Are we talking about objects or variables now? – bash.d Apr 03 '13 at 08:13
  • @bash.d for the case Guffa describes. That is the semantics of `user = new UserDetails()` depends on whether the `user`parameter is declared with or with out ref. If it's declared with `ref` then the assignment is visible outside the method (Ie. the variable used as argument now points to a different object than when the method was called). Not usinging ref the variable outside the method still points to the same object – Rune FS Apr 03 '13 at 08:13
  • @bash.d both. ref potentially impacts what variables outside the method scope refers to – Rune FS Apr 03 '13 at 08:15
  • If I pass an object without `ref` into a method, changes to this object are not persistent. C# is call-by-value, so a copy is created inside the method. [This](http://msdn.microsoft.com/en-us/library/s6938f28.aspx) is what I am talking about. – bash.d Apr 03 '13 at 08:17
  • The fact that parameters are passed by value doesn't mean that reference types are copied when passed as parameters. It means that the reference to the object is copied. The parameter is a variable in the method, which contains a copy of the reference to the object that you pass in. If you use the `ref` keyword, the parameter is the same variable as the one that you pass into the method, so changing the value of the parameter changes the variable that you passed in. – Guffa Apr 03 '13 at 08:50
  • So, the references are NOT equals, then? – bash.d Apr 03 '13 at 08:52
  • The references have the same value (pointing to the same object), as one is a copy of the other, but they are two separate references. – Guffa Apr 03 '13 at 08:57
  • The page that you linked to describes it, and here is another: http://msdn.microsoft.com/en-us/library/0f66670z%28v=VS.71%29.aspx – Guffa Apr 03 '13 at 09:03
0

You might do well to look up the concepts of the Repository Pattern and OOD. In general, I prefer projections or fully loaded entities.

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

Note: ref is not required, because all objects are passed by reference.

Troy Alford
  • 26,660
  • 10
  • 64
  • 82
DerAbt
  • 337
  • 1
  • 5
  • 14
0

You can fill your entity in its constructor method or another method inside entity class. It will be ready to use when created.

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
    }
}