在C#中,`new object()`和`new {}`有什么不同?

58

首先我在Stack Overflow上进行了搜索,找到了以下链接:

但是我对这个答案不满意,解释得不够清楚(我没有理解清楚)。基本上,我想知道 `new object()` 和 `new {}` 之间的区别。它们在编译时和运行时如何处理?

其次,我有下面这段代码,我已经在我的 ASP.NET 简单应用程序中用于 WebMethods

[WebMethod]
[ScriptMethod(UseHttpGet = false)]
public static object SaveMenus(MenuManager proParams)
{
    object data = new { }; // here im creating an instance of an 'object' and i have typed it `new {}` but not `new object(){}`.
    try
    {
        MenuManager menu = new MenuManager();    
        menu.Name = proParams.Name;
        menu.Icon = proParams.Icon;
        bool status = menu.MenuSave(menu);
        if (status)
        {
            // however, here i'm returning an anonymous type
            data = new
            {
                status = true,
                message = "Successfully Done!"
            };
        }
    }
    catch (Exception ex)
    {
        data = new { status = false, message = ex.Message.ToString() };
    }
    return data;
}

那么,(如您在代码注释中所见),new object(){}new {}有何不同?

这是否是我编写代码的正确方式? 您能为此代码提供最佳建议吗?

我知道我无法很好地解释它,而且我要求很多,但这是我现在拥有的最好的。


7
你的 new{} 创建了一个匿名类型。 - CodesInChaos
4
new {} 表示匿名类型,而 new object() 则是 Object 类的构造函数。 - Cybermaxs
我得到了-1的评分,但这并不是一个非常糟糕的问题。 - Idrees Khan
1
@Cybermaxs-Betclic,我知道结果类型是一个匿名对象类型,但它们在 MSIL 中如何处理?这会由 C# 编译器生成一个新的 Anonymouse 类型的分离代码吗? - Idrees Khan
1
这对我来说是新信息。我可以使用 new {} 来创建所有对象类型的实例吗? - Subin Jacob
请注意,如果您声明了 var a = new { };var o = new object();,则有一个区别,前者只能分配给另一个类似的匿名对象,而后者作为对象,可以被分配给任何东西。 - nawfal
3个回答

64

new {...} 总是创建一个匿名对象,例如:

  Object sample = new {};
  String sampleName = sample.GetType().Name; // <- something like "<>f__AnonymousType0" 
                                             //                    not "Object"

当使用 new Object() 时,会创建一个 Object 类的实例。

  Object sample = new Object() {};
  String sampleName = sample.GetType().Name; // <- "Object"

由于所有对象(包括匿名对象)都是从Object派生而来,因此您始终可以键入

  Object sample = new {};

更好的解释。因此,这意味着它们在运行时被视为“对象”类型,编译器不将其视为“匿名”类型。 - Idrees Khan
5
你的意思是什么,"@DotNetDreamer What do you mean "they are treated as an object type at runtime"? All objects inherit from the Object class, but Dimitry's example specifically shows that the anonymous object's actual type is not Object."?所有对象都继承自Object类,但Dimitry的例子特别指出匿名对象的实际类型不是Object,你的意思是它们在运行时被视为对象类型吗? - JLRishe

13

为了看到new Object()new {}以及new Object(){}之间的区别……我们何不试试呢?

Console.WriteLine(new Object().GetType().ToString());
Console.WriteLine(new Object() { }.GetType().ToString());
Console.WriteLine(new { }.GetType().ToString());

前两种方法只是创建对象并打印System.Object的不同方式。第三种实际上是一个匿名类型,打印<>f__AnonymousType0

我认为你可能会对'{}'的不同用法感到困惑。就我所知,它可以用于:

  1. 语句块。
  2. 对象/集合/数组初始化器。
  3. 匿名类型。

因此,简而言之,object data = new { };不会创建一个新对象。它创建一个新的匿名类型,类似于所有类、结构、枚举和委托,继承自Object,因此可以被赋给它。


如评论所述,在返回匿名类型时,仍然需要声明并向下转换为Object。但它们仍然是不同的东西,并且有一些实现差异,例如:

static void Main(string[] args)
{
    Console.WriteLine(ReturnO(true).ToString());  //"{ }"
    Console.WriteLine(ReturnO(false).ToString());  // "System.Object"

    Console.WriteLine(ReturnO(true).Equals(ReturnO(true)));  //True
    Console.WriteLine(ReturnO(false).Equals(ReturnO(false)));  //False
    Console.WriteLine(ReturnO(false).Equals(ReturnO(true)));  //False

    Console.WriteLine(ReturnO(true).GetHashCode());  //0
    Console.WriteLine(ReturnO(false).GetHashCode());  //37121646

    Console.ReadLine();
}

static object ReturnO(bool anonymous)
{
    if (anonymous) return new { };
    return new object();
}

我的 webmethod 返回值是 anonymouseobject 类型? - Idrees Khan
1
返回类型是对象 - 你不能返回匿名类型,因为...在编译时你实际上不知道类型是什么。然而,返回一个匿名类型(向下转换为对象)和返回一个对象可能会导致不同的行为 - 例如,它们以不同的方式实现ToString()方法。 - NPSF3000
1
谢谢您提供的新信息。我希望我能给您超过+1的评价 :) - Idrees Khan

8

new{ }创建一个没有成员的匿名类型实例。这与创建object实例不同。但像几乎所有类型一样,匿名类型可以分配给对象。

 object data = new { };
 Console.WriteLine(data.GetType().Name)

清晰地显示出自动生成的名称,而不是Object


“就像几乎所有类型一样,匿名类型可以分配给对象”,你能说出一个不能分配的吗? - p.s.w.g
4
明显的例子是指针。我认为还有一些其他的东西,比如那些奇怪的参数迭代器或某些类型的引用,在C#中不能直接使用。 - CodesInChaos
C# 中的指针,虽然不安全,但所有内容都在“安全”部分。 - Mare Infinitus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接