使用或不使用C#'new'关键字设置对象属性

时间:2016-05-24 09:20:54

标签: c#

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

以下是一个示例,用于说明我所指的内容,在案例1和案例2下显示。尽可能打算使用案例2(看起来整洁如一个单一语句)但无法确定C#{{ 1}}关键字有任何缺点,如增加内存使用量。 @Dennis_E我已经投了+1; - )

修订补充: 谢谢大家的快速评论和回答。你知道评论和答案慢慢相关的点,你提出问题时你从未想过。请原谅我修改,但希望你理解。

假设案例1和案例2中的代码被多次使用(例如,当您导航到视图页面时)案例2在增加内存方面存在缺点。也许我在这里做了一个错误的假设 - 'new'ing up the same变量创建一个新对象?可能这是根本问题。

new

2 个答案:

答案 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函数中创建的。

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