2016-05-24 58 views
0

使用或不使用关键字new设置对象属性是否存在根本区别?使用或不使用C#'new'关键字来设置对象属性

下面是一个例子来说明我所指的是情况1和情况2下显示的情况。只要有可能打算使用情况2(看起来整齐地作为单个语句),但不能确定是否C#new关键字有任何缺点,如增加内存使用率。 @Dennis_E我已经投了+1 ;-)

修正后的增补: 谢谢大家,提示意见和回答。你知道评论和回答慢跑相关点,你提出问题时你从来没有想过。原谅我修改,但希望你明白。

假设案例1和案例2中的代码被无数次使用(比如在浏览页面时),案例2在增加内存方面有缺点。也许我在这里做了一个错误的假设 - 是否'新建'同一个变量创建一个新的对象?可能是这个根本问题。

public static class MyCache 
    { 
     public static NameIdObject MyCacheObject = new NameIdObject(); 
    } 

    public class NameIdObject 
    { 
     public string Name { get; set; } 
     public int Id { get; set; } 
    } 

    // Usage 1: without new keyword 

    MyCache.MyCacheObject.Name = "foo"; 
    MyCache.MyCacheObject.Id = 123; 

    // Usage 2: with new keyword 

    MyCache.MyCacheObject = new NameIdObject { Id = 123, Name = "foo" }; 
+0

这两种情况在对象构造方式上都是相似的。“MyCache.MyCacheObject”总是被初始化。 –

+1

关于记忆力,他们几乎是平等的。情况2使用延迟实例化,这会延迟内存分配。这更多的是设计决定。编辑:这假定,在情况2中,你不直接在'MyCache'中初始化对象。 –

回答

3

new关键字与设置属性无关。它创建一个新的对象。但是,对象初始值设定项只能与创建新对象结合使用。

声明

MyCache.MyCacheObject = new NameIdObject { Id = 123, Name = "foo" }; 

是一个对象初始化。这仅仅是写的一个更方便的方式(并且是等同于):

MyCache.MyCacheObject = new NameIdObject(); 
MyCache.MyCacheObject.Id = 123; 
MyCache.MyCacheObject.Name = "foo"; 

你的第一个代码示例仅设置属性值。它没有实例化一个新的对象。 (你早就应该在单独的声明中完成)
所以最根本的区别是:你正在创建一个新的对象。

+0

谢谢@Dennis_E - 看过答案,可能是我的问题需要修改一下。假设案例1和案例2中的代码被无数次使用(比如在浏览页面时),案例2在增加内存方面存在缺陷。也许我在这里做出了一个错误的假设 - 在相同的变量上创建另一个对象吗?可能是这个根本问题。 – user2921851

+1

类别。每次你打电话给'新'时,你都会创建一个对象的新实例。这招致了计算开销(以及堆栈上的新指针等)。由于不再有任何对旧对象的引用,它将被垃圾收集器清理(在某个时刻),但是在很短的时间内,这两个对象都将存在于内存中。 – richzilla

+1

我不确定我的理解。每次你调用'new'时,你都在创建一个新的对象。然后你的变量将引用这个新的对象。旧对象仍然在内存中(但不再由您的变量引用)。如果您只更改属性值,则不会创建新对象。 –

1

好的方法来检查这是写小文件,编译它们并检查与IL间谍他们在中间语言中做什么。如果我这样做,我遇到这种情况。这是C#代码。

using System; 

namespace test 
{ 
    public class NameIdObject 
    { 
     public string Name { get; set; } 
     public int Id { get; set; } 
    } 

    public static class MyCache 
    { 
     public static NameIdObject MyCacheObject = new NameIdObject(); 
    } 

    public static class Program 
    { 
     public static void Main() 
     { 
      MyCache.MyCacheObject.Name = "foo"; 
      MyCache.MyCacheObject.Id = 123; 

     } 
    } 
} 

案例2

using System; 

namespace test 
{ 
    public class NameIdObject 
    { 
     public string Name { get; set; } 
     public int Id { get; set; } 
    } 

    public static class MyCache 
    { 
     public static NameIdObject MyCacheObject; 
    } 

    public static class Program 
    { 
     public static void Main() 
     { 
      MyCache.MyCacheObject = new NameIdObject { Id = 123, Name = "foo" }; 
     } 
    } 
} 

当您编译低谷开发命令行。有关详细信息,请参见https://msdn.microsoft.com/en-us/library/78f4aasd.aspx。您可以查看与IL间谍中间语言

下面是结果:

案例1

.namespace test 
{ 
    .class public auto ansi abstract sealed beforefieldinit test.MyCache 
     extends [mscorlib]System.Object 
    { 
     // Fields 
     .field public static class test.NameIdObject MyCacheObject 

     // Methods 
     .method private hidebysig specialname rtspecialname static 
      void .cctor() cil managed 
     { 
      // Method begins at RVA 0x207b 
      // Code size 11 (0xb) 
      .maxstack 8 

      IL_0000: newobj instance void test.NameIdObject::.ctor() 
      IL_0005: stsfld class test.NameIdObject test.MyCache::MyCacheObject 
      IL_000a: ret 
     } // end of method MyCache::.cctor 

    } // end of class test.MyCache 

    .class public auto ansi beforefieldinit test.NameIdObject 
     extends [mscorlib]System.Object 
    { 
     // Fields 
     .field private string '<Name>k__BackingField' 
     .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
      01 00 00 00 
     ) 
     .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (
      01 00 00 00 00 00 00 00 
     ) 
     .field private int32 '<Id>k__BackingField' 
     .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
      01 00 00 00 
     ) 
     .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (
      01 00 00 00 00 00 00 00 
     ) 

     // Methods 
     .method public hidebysig specialname 
      instance string get_Name() cil managed 
     { 
      .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
       01 00 00 00 
      ) 
      // Method begins at RVA 0x2050 
      // Code size 7 (0x7) 
      .maxstack 8 

      IL_0000: ldarg.0 
      IL_0001: ldfld string test.NameIdObject::'<Name>k__BackingField' 
      IL_0006: ret 
     } // end of method NameIdObject::get_Name 

     .method public hidebysig specialname 
      instance void set_Name (
       string 'value' 
      ) cil managed 
     { 
      .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
       01 00 00 00 
      ) 
      // Method begins at RVA 0x2058 
      // Code size 8 (0x8) 
      .maxstack 8 

      IL_0000: ldarg.0 
      IL_0001: ldarg.1 
      IL_0002: stfld string test.NameIdObject::'<Name>k__BackingField' 
      IL_0007: ret 
     } // end of method NameIdObject::set_Name 

     .method public hidebysig specialname 
      instance int32 get_Id() cil managed 
     { 
      .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
       01 00 00 00 
      ) 
      // Method begins at RVA 0x2061 
      // Code size 7 (0x7) 
      .maxstack 8 

      IL_0000: ldarg.0 
      IL_0001: ldfld int32 test.NameIdObject::'<Id>k__BackingField' 
      IL_0006: ret 
     } // end of method NameIdObject::get_Id 

     .method public hidebysig specialname 
      instance void set_Id (
       int32 'value' 
      ) cil managed 
     { 
      .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
       01 00 00 00 
      ) 
      // Method begins at RVA 0x2069 
      // Code size 8 (0x8) 
      .maxstack 8 

      IL_0000: ldarg.0 
      IL_0001: ldarg.1 
      IL_0002: stfld int32 test.NameIdObject::'<Id>k__BackingField' 
      IL_0007: ret 
     } // end of method NameIdObject::set_Id 

     .method public hidebysig specialname rtspecialname 
      instance void .ctor() cil managed 
     { 
      // Method begins at RVA 0x2072 
      // Code size 8 (0x8) 
      .maxstack 8 

      IL_0000: ldarg.0 
      IL_0001: call instance void [mscorlib]System.Object::.ctor() 
      IL_0006: nop 
      IL_0007: ret 
     } // end of method NameIdObject::.ctor 

     // Properties 
     .property instance string Name() 
     { 
      .get instance string test.NameIdObject::get_Name() 
      .set instance void test.NameIdObject::set_Name(string) 
     } 
     .property instance int32 Id() 
     { 
      .get instance int32 test.NameIdObject::get_Id() 
      .set instance void test.NameIdObject::set_Id(int32) 
     } 

    } // end of class test.NameIdObject 

    .class public auto ansi abstract sealed beforefieldinit test.Programm 
     extends [mscorlib]System.Object 
    { 
     // Methods 
     .method public hidebysig static 
      void Main() cil managed 
     { 
      // Method begins at RVA 0x2087 
      // Code size 31 (0x1f) 
      .maxstack 8 
      .entrypoint 

      IL_0000: nop 
      IL_0001: ldsfld class test.NameIdObject test.MyCache::MyCacheObject 
      IL_0006: ldstr "foo" 
      IL_000b: callvirt instance void test.NameIdObject::set_Name(string) 
      IL_0010: nop 
      IL_0011: ldsfld class test.NameIdObject test.MyCache::MyCacheObject 
      IL_0016: ldc.i4.s 123 
      IL_0018: callvirt instance void test.NameIdObject::set_Id(int32) 
      IL_001d: nop 
      IL_001e: ret 
     } // end of method Programm::Main 

    } // end of class test.Programm 

} 

案例现在2

.namespace test 
{ 
    .class public auto ansi abstract sealed beforefieldinit test.MyCache 
     extends [mscorlib]System.Object 
    { 
     // Fields 
     .field public static class test.NameIdObject MyCacheObject 

    } // end of class test.MyCache 

    .class public auto ansi beforefieldinit test.NameIdObject 
     extends [mscorlib]System.Object 
    { 
     // Fields 
     .field private string '<Name>k__BackingField' 
     .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
      01 00 00 00 
     ) 
     .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (
      01 00 00 00 00 00 00 00 
     ) 
     .field private int32 '<Id>k__BackingField' 
     .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
      01 00 00 00 
     ) 
     .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (
      01 00 00 00 00 00 00 00 
     ) 

     // Methods 
     .method public hidebysig specialname 
      instance string get_Name() cil managed 
     { 
      .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
       01 00 00 00 
      ) 
      // Method begins at RVA 0x2050 
      // Code size 7 (0x7) 
      .maxstack 8 

      IL_0000: ldarg.0 
      IL_0001: ldfld string test.NameIdObject::'<Name>k__BackingField' 
      IL_0006: ret 
     } // end of method NameIdObject::get_Name 

     .method public hidebysig specialname 
      instance void set_Name (
       string 'value' 
      ) cil managed 
     { 
      .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
       01 00 00 00 
      ) 
      // Method begins at RVA 0x2058 
      // Code size 8 (0x8) 
      .maxstack 8 

      IL_0000: ldarg.0 
      IL_0001: ldarg.1 
      IL_0002: stfld string test.NameIdObject::'<Name>k__BackingField' 
      IL_0007: ret 
     } // end of method NameIdObject::set_Name 

     .method public hidebysig specialname 
      instance int32 get_Id() cil managed 
     { 
      .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
       01 00 00 00 
      ) 
      // Method begins at RVA 0x2061 
      // Code size 7 (0x7) 
      .maxstack 8 

      IL_0000: ldarg.0 
      IL_0001: ldfld int32 test.NameIdObject::'<Id>k__BackingField' 
      IL_0006: ret 
     } // end of method NameIdObject::get_Id 

     .method public hidebysig specialname 
      instance void set_Id (
       int32 'value' 
      ) cil managed 
     { 
      .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
       01 00 00 00 
      ) 
      // Method begins at RVA 0x2069 
      // Code size 8 (0x8) 
      .maxstack 8 

      IL_0000: ldarg.0 
      IL_0001: ldarg.1 
      IL_0002: stfld int32 test.NameIdObject::'<Id>k__BackingField' 
      IL_0007: ret 
     } // end of method NameIdObject::set_Id 

     .method public hidebysig specialname rtspecialname 
      instance void .ctor() cil managed 
     { 
      // Method begins at RVA 0x2072 
      // Code size 8 (0x8) 
      .maxstack 8 

      IL_0000: ldarg.0 
      IL_0001: call instance void [mscorlib]System.Object::.ctor() 
      IL_0006: nop 
      IL_0007: ret 
     } // end of method NameIdObject::.ctor 

     // Properties 
     .property instance string Name() 
     { 
      .get instance string test.NameIdObject::get_Name() 
      .set instance void test.NameIdObject::set_Name(string) 
     } 
     .property instance int32 Id() 
     { 
      .get instance int32 test.NameIdObject::get_Id() 
      .set instance void test.NameIdObject::set_Id(int32) 
     } 

    } // end of class test.NameIdObject 

    .class public auto ansi abstract sealed beforefieldinit test.Program 
     extends [mscorlib]System.Object 
    { 
     // Methods 
     .method public hidebysig static 
      void Main() cil managed 
     { 
      // Method begins at RVA 0x207b 
      // Code size 33 (0x21) 
      .maxstack 8 
      .entrypoint 

      IL_0000: nop 
      IL_0001: newobj instance void test.NameIdObject::.ctor() 
      IL_0006: dup 
      IL_0007: ldc.i4.s 123 
      IL_0009: callvirt instance void test.NameIdObject::set_Id(int32) 
      IL_000e: nop 
      IL_000f: dup 
      IL_0010: ldstr "foo" 
      IL_0015: callvirt instance void test.NameIdObject::set_Name(string) 
      IL_001a: nop 
      IL_001b: stsfld class test.NameIdObject test.MyCache::MyCacheObject 
      IL_0020: ret 
     } // end of method Program::Main 

    } // end of class test.Program 

} 

这个信息,你面包车分析系统在你的代码中做了什么。您可以在案例1中看到NameIdObject的实例是在MyCache对象的构造函数中创建的。而在情况2中,在程序的主函数中创建了NameIdObject的实例。

因此,创建对象实例的位置以及实例创建的时间不同。我希望这有助于确定哪种情况对您的程序最有效。

+0

感谢您抽出宝贵时间对答案进行更深入的了解。 – user2921851

相关问题