Dziś zmiany w C# pod względem możliwości out i ref. Mają ona ułatwić nam pracę z językiem, więc są raczej bardziej kosmetyczne ale bym też powiedział znaczące.

Z cyklu nowości w C# 7, do tej pory ukazały się artykuły:

  1. C# 7: Tuples
  2. C# 7: Pattern Matching
  3. C# 7: out i ref
  4. C# 7: Funkcje lokalne
  5. C# 7: Lukier składniowy

Side node: wszystkie przykłady zostały przetestowane na VS 2017 RC.

out

Do tej pory jak chcieliśmy zadeklarować parametry out by potem wykorzystać je jako argumenty out to musieliśmy stworzyć zmienną/zmienne określonego typu i dopiero potem wykorzystać ją jako argument out w funkcji:

int x;
inc(out x);

Co było dość uporczliwe przy TryParse:

int i;
int.TryParse("10", out i);

Do tego, nie mogliśmy wykorzystywać słowa kluczowego var, gdyż typ danych musiał być znany kompilatorowi.

Teraz zaś, w C# 7, możemy zrobić dwie rzeczy. Rzecz pierwsza to, wykorzystać inline deklarację z wywołaniem funkcji:

inc(out int x);

Rzecz druga to, pominąć typ i wykorzystać var:

inc(out var x);

A to ze względu, że typ danych może zostać wywnioskowany poprzez kompilator przez analizę ciała funkcji inc.

Jest jeszcze jedna rzecz, która już nie wiadomo czy wejdzie do C#, a mianowicie opcjonalne argumenty z wykorzystaniem słowa kluczowego out:

var i = inc(out *);

Gdzie * oznacza, że nas nie interesują parametry.

Do tego, pamiętacie w zeszłym tygodniu przykład:

int i = 0;
object o = "34";
if(o is string s && int.TryParse(s, out i))
{
    Console.WriteLine(i);
}

To teraz, wiedząc o out można to napisać w następujący sposób:

object o = "34";

if(o is string s && int.TryParse(s, out  var i))
{
    Console.WriteLine(i);
}

ref

Słowo kluczowe ref zaś zwiększyło swój zasięg z deklaracji parametrów i podania argumentów do definicji zmiennej lokalnej jak i zwróceniu wartości z funkcji.

Do tej pory mieliśmy taką sytuację:

public int smth(ref int x, ref int y) 
{
    x = 10;
    y = 20;

    return x + y;
}

var x = 1;
var y = 1;
var sum = add(ref x, ref y);
Console.WriteLine($"{sum} = {x} + {y}");

Teraz możemy się trochę pobawić (dla prostoty, zakładam, że tablica ma 3 elementy):

public static ref int smth(int[] tab)
{
    return ref tab[1];
}

int[] tab = { 22, -10, 22 };
ref int minus_ten = ref smth(tab);
Console.WriteLine(tab[1] == -10);

minus_ten = 22;
Console.WriteLine(tab[1] == 22);

Choć tyle tych ref trzeba wstawiać, że aż się odechciewa :)

Podsumowanie

Kolejne dwie nowości, gdzie jedna jest przydatna, druga brzmi świetnie ale imo za często trzeba pisać to ref. Niby rozumiem czemu, ale i tak. Można łatwo się pogubić i o tym zapomnieć.

5 KOMENTARZE

    • Przy normalnych aplikacjach ref rzadko jest sotosowany – i imo ciekawe porównianie z goto :) Jednak przy aplikacjach które już korzystają z windows api, lub ostro działają na value types, to wtedy ref ma ręce i nogi.

    • tak i nie. tak było, nie było za to to co zostało teraz wprowadzone. Proponuje zapoznać się z postem który pokazuje co było do tej pory możliwe a co teraz jest.

      Więc tak, jest to nowość – out i ref zostały rozszerzone o dodatkowe opcje. tak samo jak is przy Pattern Maching.

Comments are closed.