创建对象然后返回或直接创建并返回之间有什么区别吗

本文关键字:返回 之间 什么 区别 创建 然后 创建对象 | 更新日期: 2023-09-27 18:25:31

对不起标题,很难说。请看我的例子
GetUser1和GetUser2之间有什么区别吗?

class Program
{
    static void Main(string[] args)
    {
        GetUser1();
        GetUser2();
    }
    private static User GetUser1()
    {
        return new User
    {
            Name = "Hello"
    };
    }
    private static User GetUser2()
    {
        User user = new User
        {
            Name = "Hello"
        };
        return user;
    }
}
public class User
{
    public string Name { get; set; }
}

我的一个朋友在说;没有区别
但我是这么说的;两种方法有区别。GetUser2正在创建一个不必要的新对象。GetUser2有一个小(非常小)的性能错误,因为您正在创建一个新对象。。。真相是什么?我该如何研究这个话题?

更新
非常感谢你的回答。。。所以我继续问
如果GetUser1和GetUser2之间没有区别,为什么roslyn编译这样的代码(链接);

private static User GetUser1()
{
    return new User {
        Name = "Hello"
    };
}

创建对象然后返回或直接创建并返回之间有什么区别吗

发布模式编译时没有区别。如果您在调试模式中查看发出的IL,您会注意到在返回对象之前存储和加载变量的附加stloc/ldloc指令的形式存在细微差异。

如果你查看生成的编译器代码,你会得到两个相同的结果:

private static void Main(string[] args)
{
    Program.GetUser1();
    Program.GetUser2();
}
private static User GetUser1()
{
    return new User {
        Name = "Hello"
    };
}
private static User GetUser2()
{
    return new User {
        Name = "Hello"
    };
}

以及为两者生成的IL代码:

.method private hidebysig static 
    class User GetUser1 () cil managed 
{
    // Method begins at RVA 0x2068
    // Code size 17 (0x11)
    .maxstack 8
    IL_0000: newobj instance void User::.ctor()
    IL_0005: dup
    IL_0006: ldstr "Hello"
    IL_000b: callvirt instance void User::set_Name(string)
    IL_0010: ret
} // end of method Program::GetUser1
.method private hidebysig static 
    class User GetUser2 () cil managed 
{
    // Method begins at RVA 0x2068
    // Code size 17 (0x11)
    .maxstack 8
    IL_0000: newobj instance void User::.ctor()
    IL_0005: dup
    IL_0006: ldstr "Hello"
    IL_000b: callvirt instance void User::set_Name(string)
    IL_0010: ret
} // end of method Program::GetUser2

在没有抖动优化的调试构建中有一个微小的差异,因为冗余没有被删除,所以您可以更容易地在调试器中检查值。

发布版本将删除它,抖动优化也可以这样做,所以除了调试情况之外,两者是相同的。

两种方法有区别。GetUser2正在创建一个不必要的新对象。GetUser2有一个小(非常小)的性能错误,因为您正在创建一个新对象。

两个方法都在创建一个新对象。使用中间变量(User user)的方法只添加了一个:一个变量,它只是指向同一对象的指针。

一旦方法超出范围,变量就不存在了。

即使在调试模式下,堆栈上多了一个变量的差异也绝对可以忽略不计。