使用或不使用new
关键字设置对象属性是否存在根本区别?
以下是一个示例,用于说明我所指的内容,在案例1和案例2下显示。尽可能打算使用案例2(看起来整洁如一个单一语句)但无法确定C#{{ 1}}关键字有任何缺点,如增加内存使用量。 @Dennis_E我已经投了+1; - )
修订补充: 谢谢大家的快速评论和回答。你知道评论和答案慢慢相关的点,你提出问题时你从未想过。请原谅我修改,但希望你理解。
假设案例1和案例2中的代码被多次使用(例如,当您导航到视图页面时)案例2在增加内存方面存在缺点。也许我在这里做了一个错误的假设 - 'new'ing up the same变量创建一个新对象?可能这是根本问题。
new
答案 0 :(得分:3)
new
关键字与设置属性无关。它创建了一个新对象。但是,对象初始值设定项只能与创建新对象结合使用。
声明
MyCache.MyCacheObject = new NameIdObject { Id = 123, Name = "foo" };
是一个对象初始值设定项。这只是一种更方便的写作方式(相当于):
MyCache.MyCacheObject = new NameIdObject();
MyCache.MyCacheObject.Id = 123;
MyCache.MyCacheObject.Name = "foo";
您的第一个代码示例仅设置属性值。它不会实例化新对象。 (你可以在之前的单独声明中做到这一点)
因此,根本区别在于:您正在创建一个新对象。
答案 1 :(得分:1)
检查这个的好方法是编写小文件,编译它们并用IL Spy检查它们在中间语言中的作用。如果我这样做,我得到文件。这是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 Spy
查看中间语言以下是结果:
案例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的实例是在程序的main函数中创建的。
因此,创建对象实例的位置以及创建实例的时间是不同的。我希望这有助于确定哪种情况对您的计划最有效。