Сведения о вопросе

DED

20:35, 3rd August, 2020

Теги

c#   .net   vb.net    

Что делать Реф, знач и про параметры метода?

Просмотров: 480   Ответов: 4

Я ищу ясный, лаконичный и точный ответ.

В идеале в качестве фактического ответа, хотя ссылки на хорошие объяснения приветствуются.

Это также относится к VB.Net, но ключевые слова разные- ByRef и ByVal .



  Сведения об ответе

screen

21:33, 19th August, 2020

По умолчанию (в C#), передача объекта функции фактически передает копию ссылки на этот объект. При изменении самого параметра изменяется только значение параметра, а не указанная переменная.

void Test1(string param)
{
    param = "new value";
}

string s1 = "initial value";
Test1(s1);
// s1 == "initial value"

Использование out или ref передает ссылку на переменную, указанную в вызове функции. Любые изменения значения параметра out или ref будут переданы обратно вызывающему объекту.

И out , и ref ведут себя одинаково, за исключением одного небольшого отличия: перед вызовом необходимо инициализировать параметры ref , а параметры out могут быть неинициализированы. Таким образом, ref параметров гарантированно инициализируются в начале метода, а out параметров рассматриваются как неинициализированные.

void Test2(ref string param)
{
    param = "new value";
}

void Test3(out string param)
{
    // Use of param here will not compile
    param = "another value";
}

string s2 = "initial value";
string s3;
Test2(ref s2);
// s2 == "new value"
// Test2(ref s3); // Passing ref s3 will not compile
Test3(out s2);
// s2 == "another value"
Test3(out s3);
// s3 == "another value"

Edit: как указывает dp , разница между out и ref применяется только компилятором C#, а не CLR. Насколько мне известно, VB не имеет эквивалента для out и реализует только ref (как ByRef), совпадая с поддержкой CLR.


  Сведения об ответе

crush

12:19, 2nd August, 2020

Одно дополнительное примечание о Реф и из: различие между двумя обеспечивается компилятором C#. CLR не делает различия между out и ref. Это означает, что у вас не может быть двух методов, сигнатуры которых отличаются только на out или ref

void foo(int value) {}

// Only one of the following would be allowed

// valid to overload with ref
void foo(ref int value) {}

// OR with out
void foo(out int value) {}


  Сведения об ответе

KOMP

18:35, 21st August, 2020

out означает, что параметр будет инициализирован методом:

int result; //not initialised

if( int.TryParse( "123", out result ) )
   //result is now 123
else
   //if TryParse failed result has still be 
   // initialised to its default value (0)

ref заставит базовую ссылку быть переданной:

void ChangeMyClass1( MyClass input ) {
   input.MyProperty = "changed by 1";
   input = null;
   //can't see input anymore ... 
   // I've only nulled my local scope's reference
}

void ChangeMyClass2( ref MyClass input ) {
   input.MyProperty = "changed by 2";
   input = null;
   //the passed reference is now null too.
}

MyClass tester = new MyClass { MyProperty = "initial value" };

ChangeMyClass1( tester );
// now tester.MyProperty is "changed by 1"

ChangeMyClass2( ref tester );
// now tester is null


  Сведения об ответе

dump

00:11, 11th August, 2020

Один из моих собственных вопросов в stackoverflow тоже касается этой темы.
Он обрабатывает около "pass by reference" и "pass by value" в разных типах языков, c# включен , так что, возможно,вы можете найти там дополнительную информацию.

В основном это сводится к следующему:

  • ref: параметр с ключевым словом ref будет передан по ссылке
  • out: параметр с ключевым словом out будет рассматриваться как выходной параметр

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться