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
- 如果您只传递
,因为您需要的是用户的id,那么参数应该是UserDetails
。这将保持接口的内聚性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方法外的变量仍然指向同一对象