Zagadka 1 - Jak to jest możliwe?

Przegladajac poranna dawke postow na blogach (nieodlaczny Google Reader), natknalem sie na ciekawy i zaskakujacy fragmetn kodu. Zaczalem doglebniej przegladac siec i swoje zasoby dyskowe i moje zaskoczenie roslo jeszcze bardziej. Dosc gadaniny zapraszam do rozwiazania zagadki (raczej nie przewiduje nagrod). Niestety ta zagadka ma jeden feler (ktory sam nie znosze) - dobra odpowiedzia jest ta ktora mam na mysli. Czyli jest to raczej proba zainteresowania ciekawym zjawiskiem jezyke C# niz prawdziwa zagadka.

Ponizej jest fragment kody C#. Z pewnego typu wycialem kod konstruktora i pola. Pytanie: Jak to jest mozliwe?

public static readonly Aaa Empty;
public Aaa(int x, int y) {
    this = Empty;
}

"Jak" znaczy wskazac odpowiedni fragment specyfikacji języka C#.

EDIT: Poprawna odpowiedz dal "apl". Gratulacje!

public struct MyStruct {
    public static readonly MyStruct Empty;
    private int _x;
    public MyStruct(bool notUsed) {
        this = Empty;
    }
}

Warto w tym momencie przytoczyc fragment dokumentacji C# 3 dotyczacy slowa kluczowego this w kontekscie klasy i struktury:

Klasa:

"When this is used in a primary-expression within an instance constructor of a class , it is classified as a value. The type of the value is the instance type (§10.3.1) of the class within which the usage occurs, and the value is a reference to the object being constructed."

Struktura:

"When this is used in a primary-expression within an instance constructor of a struct, it is classified as a variable. The type of the variable is the instance type (§10.3.1) of the struct within which the usage occurs, and the variable represents the struct being constructed. The this variable of an instance constructor of a struct behaves exactly the same as an out parameter of the struct type—in particular, this means that the variable must be definitely assigned in every execution path of the instance constructor."

Z pierwszego zdania w obu tekstach widac ze sa traktowane inaczej w klasie i strukturze. Dodatkowo z tego co z rozumialme z reszty wyjasnienia dla struktury, to "value" nalezy traktowac jak parameter out (nalezy zainicjalizowac out-parametr przed opuszczeniem metody), czyli cos w rodzaju:

public struct MyStruct {
    public MyStruct(out MyStruct this) {
        ...
    }
}

Lecz porownujac prawdziwy parametr "out" i ten pseudo, wychodza na jaw znaczace roznice:

public struct MyStruct {
    private int _x;
    public MyStruct(/* out int this, */ int x) {
        this._x = x;
    }
}
public class MyClass {
    private int _x;
    public void MyClassMethod(out MyClass @this, int x) {
        @this._x = x;
    }
}

W drugim przypadku dostaniemy blad kompilacji "error CS0269: Use of unassigned out parameter 'this'" dla linii "@this._x = x;".

Podgladajac kod IL wygenerowany dla roznych przypadkow, dochodze do wniosku, ze konstrukcja "this =" sluzy poprostu za inicjalizator struktury zap omoca wartosci po prawej stronie znaku rownosci konstrukcji "this =". Inicjalizator w sensie "memcpy" - czyli tak jak dziala przypisanie struktur jezyka C# - kopiujac wartosca nie przypisujac referencje.

Podsumowujac, przegladajac blogi i czytajac kod (w tym przypadku MEF Preview 2), czasami mozna czegos nowego sie nauczyc ( a dokumentacje C# poprawic ;-) ).

BTW: Wyglada jak by w .NET 4, proste pojemniki na dane (takie jak opisywalem w jednym z tekstow) beda dostepne "z pudelka"!

Opublikowane 08 września 08 12:05 przez Wojciech Gebczyk

Komentarze:

# apl said on września 8, 2008 12:44:

Do specyfikacji nie chce mi się zaglądać, ale coś takiego jest możliwe jeśli Aaa jest typem bezpośrednim.

# Wojciech Gebczyk said on września 8, 2008 12:54:

ha! A co to jest "typ bezposredni"?

# apl said on września 8, 2008 13:14:

W sensie: typ niereferencyjny, struktura, value type.

# Wojciech Gebczyk said on września 8, 2008 13:28:

aaa! value type. :-) Nie wiedzialem ze taki jest polski odpowiednik tego.

Brawo! Dobra odpowiedz. W tekscie dalej druga czesc.

# arkadiusz.wasniewski said on września 8, 2008 16:34:

Proszę! Czyli można używać polskich odpowiedników: value type. Brawo.

Komentarze anonimowe wyłączone

About Wojciech Gebczyk

Code Sculptor.