Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 方法返回作为参数传递的相同对象_C#_Oop_Methods - Fatal编程技术网

C# 方法返回作为参数传递的相同对象

C# 方法返回作为参数传递的相同对象,c#,oop,methods,C#,Oop,Methods,将对象传递到方法中,然后返回相同的对象,而不是在方法本身内部创建新对象,这种做法是否可以接受 例如:如果有一个实体类,如下所示: class UserDetails { int UserID { get; set; } string UserName { get; set; } string UserAge { get; set; } } UserDetails UserInfo = new UserDetails(); UserInfo = Get_Details(U

将对象传递到方法中,然后返回相同的对象,而不是在方法本身内部创建新对象,这种做法是否可以接受

例如:如果有一个实体类,如下所示:

class UserDetails {
    int UserID { get; set; }
    string UserName { get; set; }
    string UserAge { get; set; }
}
UserDetails UserInfo = new UserDetails();
UserInfo = Get_Details(UserInfo);
然后我将这个类的一个实例传递给一个方法,如下所示:

class UserDetails {
    int UserID { get; set; }
    string UserName { get; set; }
    string UserAge { get; set; }
}
UserDetails UserInfo = new UserDetails();
UserInfo = Get_Details(UserInfo);
该方法执行以下操作是否合理

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

这对于(当您希望逐步构建复杂对象时)非常有用

作为一个非常糟糕的例子:

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

  Foo ToFoo();
}

new FooBuilder().WithAge(12).WithUrl(new Url("http://www.happybirthday.com/").ToFoo();
在您的特定情况下,我更喜欢使用初始化器语法一次性初始化所有内容

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

这是一种可能的方法,当你只有一项工作时,也是最好的。您也可以考虑使用<代码> REF ,它创建了对传递的参数

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

这样,您就不会传递副本,而是引用传入的对象。但这可能变得相当模糊,在您的情况下是不必要的。有关详细信息,请参阅。

您最好查阅存储库模式和OOD的概念。一般来说,我更喜欢投影或完全加载的实体

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

注意:ref不是必需的,因为所有对象都是通过引用传递的。

IMO,不需要返回对象。由于它是通过引用传递给方法调用方已经有了对同一对象的引用(在方法完成后具有更新的值)

另一方面,在某些情况下有用的是流畅的接口,其中类的实例方法再次返回实例,例如:

class X
{
  public X DoThis(int number)
  {
    // do something
    return this;
  }
  public X DoThat(string name)
  {
    // do something else
    return this;
  }
}
这允许编写非常可读的代码,例如:

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

这样做是毫无意义的,因为你所做的作业不会改变任何事情

这样称呼:

UserInfo = Get_Details(UserInfo);
给出与调用它并忽略返回值相同的结果:

Get_Details(UserInfo);
返回引用可能只会让人感到困惑,让人相信该方法会返回一个新实例,因为这是返回引用的唯一逻辑原因

在类中使用该方法更有意义,因此您可以将其称为:

UserInfo.Get_Details();
如果你的方法应该初始化对象,你宁愿把代码放在构造函数中,而不是在创建实例后调用它:

class UserDetails {

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

  public UserDetails() {
    Get_Details(this);
  }

}
然后创建实例,构造函数加载数据:

UserDetails UserInfo = new UserDetails();

这没有什么可怕的错误,只有几个观察结果

  • 您正在一个名为
    get
    的方法中设置细节,也许
    load
    更合适
  • 如果您只传递
    UserDetails
    ,因为您需要的是用户的id,那么参数应该是
    id
    。这将保持接口的内聚性
  • 在方法中修改参数对象通常被认为是不好的形式,即变异原理

您可以在实体类中的构造函数方法或其他方法中填充实体。创建后即可使用

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

观察到,您正在设置细节,而不是获取细节:-一件小事:您的函数名具有误导性(我猜名为
Get\u details
的函数不会更改其输入)。除此之外,您所说明的实践是正确的。也许这应该放在代码复查堆栈交换上?我相信这称为Grass/Goose模式。如果您想更改实际引用,您只会使用
ref
关键字。不使用
ref
关键字传递它不会创建对象的副本,它只会创建引用的副本。这没有意义。。。为什么会有
ref
呢?关键字
ref
会创建一个对保存引用的变量的引用(或者保存值的变量,如果它是值类型的话)。您可以更改从方法内部传入的变量。我们现在讨论的是对象还是变量?@bash.d用于Guffa描述的情况。这就是
user=new UserDetails()
的语义,它取决于
user
参数是用out ref声明的还是用out ref声明的。如果它是用
ref
声明的,则赋值在方法外部可见(即用作参数的变量现在指向与调用方法时不同的对象)。不使用ref方法外的变量仍然指向同一对象