Looking for c# Keywords? Try Ask4Keywords

C# Language ref, out


пример

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

int x = 5;
ChangeX(ref x);
// The value of x could be different now

Для ссылочных типов экземпляр в переменной может быть изменен не только (как в случае без ref ), но также может быть полностью заменен:

Address a = new Address();
ChangeFieldInAddress(a);
// a will be the same instance as before, even if it is modified
CreateANewInstance(ref a);
// a could be an entirely new instance now

Основное различие между out и ref ключевым словом , что ref требует переменной для инициализации вызывающего, в то время как out передает , что ответственность перед вызываемым.

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

int number = 1;
Console.WriteLine("Before AddByRef: " + number); // number = 1
AddOneByRef(ref number);
Console.WriteLine("After AddByRef: " + number);  // number = 2
SetByOut(out number);
Console.WriteLine("After SetByOut: " + number);  // number = 34

void AddOneByRef(ref int value)
{
    value++;
}

void SetByOut(out int value)
{
    value = 34;
}

Живая демонстрация на .NET скрипке

Ниже не компилируется, так как out параметров должен иметь значение , присвоенное до возврата метода (он будет компилировать с помощью ref , а):

void PrintByOut(out int value)
{
    Console.WriteLine("Hello!");
}

использование ключевого слова как Generic Modifier

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

Ковариация позволяет использовать более производный тип, чем тот, который задан общим параметром. Это позволяет неявное преобразование классов, которые реализуют варианты интерфейсов и неявное преобразование типов делегатов. Ковариантность и контравариантность поддерживаются для ссылочных типов, но они не поддерживаются для типов значений. - MSDN

//if we have an interface like this
interface ICovariant<out R> { }

//and two variables like
ICovariant<Object> iobj = new Sample<Object>();
ICovariant<String> istr = new Sample<String>();

// then the following statement is valid
// without the out keyword this would have thrown error
iobj = istr; // implicit conversion occurs here