Could you hire me? Contact me if you like what I’ve done in this article and think I can create value for your company with my skills.

January 22, 2015 / by Zsolt Soczó

.NET fejtörő 3.

Update: bocs, a Counter osztály lemaradt, így nem volt értelme a feladatnak.

Piros vagy zöld lesz a teszt kimenete? Válaszokat indoklással kommentben várom. A hozzászólások moderálva vannak, hogy 2 napot tudjam késleltetni a válaszokat, így mindenkinek lesz ideje gondolkodni. Jó filózást!


struct Counter
{
    int counter;
    public override string ToString()
    {
        return counter++.ToString(CultureInfo.InvariantCulture);
    }
}

[TestMethod]
public void Teaser3()
{
    var sb = new StringBuilder();
            
    var sz = new Counter();
            
    sb.Append(sz);
    Object p = sz;
    Object o = p;
    sb.Append(sz);
    sb.Append(o);
    sb.Append(p);
    sb.Append(o);

    Assert.AreEqual("01234", sb.ToString());
}

A Test Driven Development tanfolyam következő felvonása 2015. február kilencedikén lesz, szeretettel várlak.

Could you hire me? Contact me if you like what I’ve done in this article and think I can create value for your company with my skills.

LEAVE A COMMENT

10 COMMENTS

  • Nagypál Gábor February 6, 2015

    A StringBuilder.Append() az egyszerű típusokra (numerikus, string, karakter tömb), és az object típusra tartalmaz overload-ot. Utóbbi a paraméterben kapott értéket az Object.ToString() meghívásával alakítja át string-gé. Akkor lenne sikeres a teszt, ha a Counter.ToString() override implementálva lenne, és az a ToString() meghívások számát adná vissza.

  • Molnár Csaba February 6, 2015

    Amennyiben valami ilyesmi a Counter kódja, akkor zöld lesz a teszt:
    public class Counter
    {
    private int counter = 0;

    public override string ToString()
    {
    return (counter++).ToString();
    }
    }

    Indoklás Append-enként:
    1. Az első Append-nél 0-át ír ki, onnan indul a számláló.
    2. 1-et ír ki, megy tovább a számláló.
    3. Az “o”-t iratjuk ki, aminek megegyezik a referenciája az “sz” változóval, tehát megy tovább a számláló 2-re.
    4. A “p” változót iratjuk ki, aminek a referenciája szintén megegyezik “sz” referenciájával, így a 3 jelenik meg.
    5. Az “o” referenciája még mindig azonos “sz”-ével, tehát megy tovább a számláló 4-re.

  • Simon József February 6, 2015

    Nem néztem VS-ben, de szerintem faild a teszt és ez lesz belőle: 12223

  • Simon József February 6, 2015

    Persze hülyeséget írtam. Bevallom, hogy VS használat után arra jutottam, hogy: Faild lesz 00012
    Mert: sb.Append(sz) hatására nem a struct íródik ki hanem először a structot alapján létre jön egy új object amin ha meghívom a ToString-et akkor mindíg 0-át ad vissza (mert a counter++ miatt a counter értéke csak utána növekszik meg).
    Ugyanez történik a következő sb.Append(sz) hívásakor is (új object…) mert ugye az Appendnek object kell.
    Az első sb.Append(o) nál (az o az tényleg egy object már) még nulla a counter (a counter++ miatt)
    Az sb.Append(p)-nél 1 lesz mert a p=o referenciára.
    Végül az utolsó sb.Append(o)-nál 2 lesz a counter (ami utána már megint megnövekszi de az a kutyát sem érdekel)

  • endret February 6, 2015

    Hamis lesz, a várt eredmény “00012” mert,
    a .Append(Object o) túlterheltjét fogja hívni jelen esetben mindig, viszont az első két hívásnál az “sz” értéktípus értékét felhasználva (ami 0) mindig keletkezik egy új Object (amik teljesen függetlenek egymástól) mintha ezt írnánk: Append((Object)sz)
    Így az első két hívás után 00 lesz. (Hiába történik a II. Append előtt dobozolás nincs hatással II. hívásra.)
    A harmadik hívás előtt megtörténik a dobozolás és az “o” referenciát átadva megtörténik rajta az első .ToString (ami 0-t ad) majd a referenciákkal ‘játszva’ mindig egy olyan referencia lesz átadva ami heap-en ugyanarra az objektum értékre mutat így megtörténik a számláló folyamatos léptetése (012).

  • Apró Szabolcs February 8, 2015

    Piros lesz a teszt.
    A struct érték típusú ezért az érték szerinti paraméterátadásnál a teljes struct változó értékének a másolata kerül átadásra, így a “sb.Append(sz);” mindig “0”-t ad, akárhányszor futtatjuk (feltételezve, hogy nem volt előtte sz.ToString();).
    Az “o” és az “p” már mutató típusúak, tehát az érték szerinti paraméterátadásnál az sz-re mutató hivatkozás lesz átmásolva, így bármelyikük átadása az Append()-nek azt eredményezi, hogy az eredeti “sz”-nek a “ToString()”-je lesz meghívva, tehát a counter növekszik (“0”-ról indulva).

  • Balázs Gyuri February 9, 2015

    public void Teaser3ExplicitBoxing()
    {
    var sb = new StringBuilder();

    var sz = new Counter();

    sb.Append((object)sz);
    object p = (object)sz;
    object o = p;
    sb.Append((object)sz);
    sb.Append(o);
    sb.Append(p);
    sb.Append(o);

    Assert.AreEqual(“00012”, sb.ToString());
    Assert.AreEqual(“01234”, sb.ToString());
    }