Есть ли какое-либо преимущество с ключевым словом "in" в ссылочных типах? - PullRequest
4 голосов
/ 11 марта 2019

Мне просто любопытно, есть ли преимущество использования ключевого слова in для параметра ссылочного типа (например, string)?

Пример:

bool IsNice(string greeding)
{
    return greeding.Contains(":-)");
}

VS

bool IsNice2(in string greeding)
{
    return greeding.Contains(":-)");
}

Ответы [ 3 ]

2 голосов
/ 11 марта 2019

С точки зрения производительности, вероятно, не очень. Вы добавляете дополнительную разыменование.

Возьми код

public class C
{
    public void WithoutIn(string s)
    {
        Console.WriteLine(s);
    }

    public void WithIn(in string s)
    {
        Console.WriteLine(s);
    }
}

Это выглядит как:

C.WithoutIn(System.String)
    L0000: mov ecx, edx
    L0002: call System.Console.WriteLine(System.String)
    L0007: ret

C.WithIn(System.String ByRef)
    L0000: mov ecx, [edx]
    L0002: call System.Console.WriteLine(System.String)
    L0007: ret

( 1010 * SharpLab *).

Единственная разница - mov ecx, [edx], а не mov ecx edx. Я полагаю, что разыменование немного замедлит ход событий, но не на какую-либо заметную величину.

На практике это означает, что вы не можете сделать это:

public void M(in string s)
{
    s = "foo"; // CS8331: Cannot assign to variable 'in string' because it is a readonly variable
}

in был добавлен в язык для улучшения поддержки передачи структур по ссылке. Я бы поставил под сомнение любой код, который использовал его со ссылочным типом: я бы предположил, что он возник в результате того, что тип значения впоследствии был изменен на ссылочный тип, а не из-за какого-то преднамеренного решения.

2 голосов
/ 11 марта 2019

Из " In Параметры в C # 7.2 - Ссылки только для чтения ":

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

Так что только для чтения?

0 голосов
/ 11 марта 2019

Они ведут себя по-разному.

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

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

Переменной будет довольно сложно измениться после первоначального вызова метода, поэтому я не ожидаю, что это будет иметь значение на практике очень часто, но это возможно.

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