简体   繁体   中英

method returning same object which was passed as parameter

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

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, eg:

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");

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

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, ie, mutation principle.

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.

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.

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();

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM