В чем разница между конструктором структуры с `this ()` в конце и другим без? - PullRequest
1 голос
/ 11 апреля 2019

Допустим, у нас есть эти две структуры ...

public struct Example
{
    public int Number { get; set; }

    public Example(int Number)
    {
        Number = number;
    }
}

и

public struct Example
{
    public int Number { get; set; }

    public Example(int number) : this()
    {
        Number = number;
    }
}

Вы можете видеть, что есть структура с конструктором с **this()** в конце, а другая без.

В чем разница между этими двумя?

Ответы [ 4 ]

3 голосов
/ 11 апреля 2019

Вызов this () инициализирует все поля с нулями. Компилятор C # требует инициализации всех структурных полей в конструкторе. Поэтому, если вы хотите указать не все поля, вы должны вызвать this ().

Не будет компилироваться:

struct A
{
    public int field1;
    public string field2;

     public A(string str)
     {
         field2 = str;
     }
}

Дает:

Ошибка CS0171 Поле 'A.field1' должно быть полностью назначено до того, как управление будет возвращено вызывающей стороне ...

В порядке:

struct A
{
    public int field1;
    public string field2;

    public A(string str) : this()
    {
        field2 = str;
    }
}

Странно, но все еще в порядке:

struct A
{
    public int field1;
    public string field2;

    public A(string str)
    {
        this = new A(); // in structs 'this' is assignable
        field2 = str;
    }
}

или

struct A
{
    public int field1;
    public string field2;

    public A(string str)
    {
        this = default(A); // in structs 'this' is assignable
        field2 = str;
    }
}
2 голосов
/ 11 апреля 2019

В вашем примере нет никаких поведенческих изменений, так как this() вызывает конструктор без параметров для структуры, которая не определена.

Обратите внимание, что в C # 6.0 и новее вы не можете переопределить конструктор структуры без параметров, поэтому если вы сделаете:

public struct Example
{
    public Example() // compile error in c# 6.0 and up
    {
    }
}

Вы получите ошибку компиляции. Подробнее здесь .

В более старых версиях C # вы можете переопределить конструктор без параметров, что означает, что вы можете добавить дополнительное поведение в свой параметризованный конструктор, изменив безпараметрический.

Помимо этого, теоретически может снизиться производительность из-за дополнительного кода IL, сгенерированного для конструктора this():

Example..ctor:
IL_0000:  ldarg.0     
IL_0001:  initobj     UserQuery.Example
IL_0007:  nop         
IL_0008:  ldarg.0     
IL_0009:  ldarg.1     
IL_000A:  call        UserQuery+Example.set_Number
IL_000F:  nop         
IL_0010:  ret 
2 голосов
/ 11 апреля 2019

ОБНОВЛЕНО

Для класса :

Разница в том, что конструктор, который вызывает this(), также будет вызывать конструктор класса, который не принимает аргументов. Так, например, если это был ваш класс:

public class Example
{
    public int Number { get; set; }

    public Example(int number) : this()
    {
        Number = number;
    }
    public Example()
    {
        Console.WriteLine("Hello");
    }
}

Тогда включение this() также выведет «Hello». Это способ объединения конструкторов для повторного использования кода.

Для структуры :

Вы не можете добавить пустой конструктор в структуру, поэтому добавление this() не дает никаких преимуществ. Спасибо vendettamit за то, что разбудил мой усталый мозг.

1 голос
/ 11 апреля 2019

Разницы нет. this() вызовет конструктор без параметров, который является обязательным для структур по определению, который ничего не сделает, если вы не переопределите его и не настроите его поведение. В случае struct s вам не разрешено определять ваш собственный конструктор без параметров; хотя с class es вы можете.

Тем не менее, обратите внимание, что построение цепочек является удобным инструментом для СУХОГО в сложных сценариях построения: то есть, когда объект предоставляет множество конструкторов с различными параметрами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...