Инициализатор объекта
Является ли инициализатор объекта в С# 3.0 быстрее, чем обычный?
Это быстрее
Object object = new Object
{
id = 1;
}
чем это?
Object object = new Object()
object.id = 1;
Ответы
Ответ 1
В режиме Release они будут скомпилированы с одним и тем же кодом IL (при условии, что вы фактически используете тип с свойством id
вместо Object
)
Следовательно, по определению не будет разницы в производительности.
Я не знаю, какой из них будет компилироваться быстрее, но это будет небольшая разница во времени компиляции, и вам, вероятно, все равно.
Однако синтаксис инициализатора объекта записывается быстрее (меньше ввода), поэтому вы, вероятно, должны его использовать.
Ответ 2
Хорошо, из комментария [SLaks] [2] и тестирования себя после прочтения, оказывается, что различие, которое я описываю здесь, присутствует только в режиме отладки. Если вы компилируете для выпуска, все они скомпилируются в один и тот же код. Узнайте что-то новое каждый день:)
(так что остальная часть ответа предполагает режим отладки.)
Существует различие в производстве ИЛ, в отличие от других, которые здесь ответили, но разница незначительна и вообще не должна влиять на вашу программу на производительность.
Разница заключается в том, что с использованием инициализатора объекта, например:
Object object = new Object
{
id = 1;
}
Код действительно скомпилирован так, как если бы вы написали это:
Object temp = new Object();
temp.id = 1;
Object object = temp;
(разумеется, за исключением того факта, что Object не имеет поля Id/property, и вы не можете фактически назвать переменную "объект" без использования синтаксиса verbatim identifier "@object".)
Зачем это? Ну, одна разница, которую вы могли бы заметить, заключается в том, что если какое-либо из заданий выкидывало исключение (либо записывая значение в объект, либо получая значение из выражения или функции, выдает исключение), то с инициализатором объекта вы выиграли ' t фактически видеть любой объект в переменной, тогда как в вашем "ручном" коде объект будет там, инициализирован вплоть до точки, в которой произошло исключение.
Небольшое отличие, которое не должно сильно отличаться от производительности, но может изменить поведение вашей программы.
Это можно проверить, посмотрев IL. Возьмите эту программу С#:
using System;
namespace ConsoleApplication3
{
class Test
{
public Int32 Id { get; set; }
}
class Program
{
static void Main(string[] args)
{
M1();
M2();
}
static void M1()
{
Test t = new Test();
t.Id = 1;
}
static void M2()
{
Test t = new Test { Id = 1 };
}
static void M3()
{
Test t;
Test temp = new Test();
temp.Id = 1;
t = temp;
}
}
}
и скомпилируйте его, запустите его через Reflector, и вы получите это для M1, M2 и M3:
.method private hidebysig static void M1() cil managed
{
.maxstack 2
.locals init (
[0] class ConsoleApplication3.Test t)
L_0000: nop
L_0001: newobj instance void ConsoleApplication3.Test::.ctor()
L_0006: stloc.0
L_0007: ldloc.0
L_0008: ldc.i4.1
L_0009: callvirt instance void ConsoleApplication3.Test::set_Id(int32)
L_000e: nop
L_000f: ret
}
.method private hidebysig static void M2() cil managed
{
.maxstack 2
.locals init (
[0] class ConsoleApplication3.Test t,
[1] class ConsoleApplication3.Test <>g__initLocal0)
L_0000: nop
L_0001: newobj instance void ConsoleApplication3.Test::.ctor()
L_0006: stloc.1
L_0007: ldloc.1
L_0008: ldc.i4.1
L_0009: callvirt instance void ConsoleApplication3.Test::set_Id(int32)
L_000e: nop
L_000f: ldloc.1
L_0010: stloc.0
L_0011: ret
}
.method private hidebysig static void M3() cil managed
{
.maxstack 2
.locals init (
[0] class ConsoleApplication3.Test t,
[1] class ConsoleApplication3.Test temp)
L_0000: nop
L_0001: newobj instance void ConsoleApplication3.Test::.ctor()
L_0006: stloc.1
L_0007: ldloc.1
L_0008: ldc.i4.1
L_0009: callvirt instance void ConsoleApplication3.Test::set_Id(int32)
L_000e: nop
L_000f: ldloc.1
L_0010: stloc.0
L_0011: ret
}
Если вы посмотрите на код, единственное, что отличается между M2 и M3, - это имя второго локального (<>g__initLocal0
vs temp
).
Но, как уже ответили другие, разница не будет отличаться от производительности.
Ответ 3
AFAIK это просто синтаксический сахар - произведенный IL будет таким же
Ответ 4
Нет, это то же самое.
Ответ 5
Быстрее вводить его, но он компилируется в один и тот же код, поэтому нет возможности выполнения.
Ответ 6
Если есть какие-либо различия в производительности (я сомневаюсь, что они есть), они незначительны. Оптимизируйте только там, где профайлер сказал вам сделать это.
Ответ 7
Я не сравнивал это, но я был бы удивлен, если бы они не скомпилировали одно и то же.
Тем не менее, мне легче вводить, когда мне нужно что-то вроде
var bob = service.GetSingle( new Constraint { UserName = "Bob" } );
Я сильно не люблю повторные присваивания свойств вроде
var c = new Constraint();
c.UserName = "Bob";
c.Position = Positions.Manager;
var bob = service.GetSingle( c );