Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

System.Windows.Forms.Keys enum i bitwise operatori.

[es] :: .NET :: System.Windows.Forms.Keys enum i bitwise operatori.

[ Pregleda: 2385 | Odgovora: 3 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

kopca

Član broj: 14307
Poruke: 118
82.117.202.*



Profil

icon System.Windows.Forms.Keys enum i bitwise operatori.08.09.2008. u 10:28 - pre 190 meseci
Postavljam pitanje radoznalosti radi.
Zamislite da imate enumeraciju:
Code:

    //[Flags]
    public enum Test : int
    {
        Six = 6,
        Seven = 7,
        Eight = 8,
        Nine = 9
    }
    ...
    Test six = Test.Six;
    Test seven = Test.Seven;
    Test eight = Test.Eight;
    Test combine = six | seven | eight;
    MessageBox.Show(combine.ToString());

MessageBox pokazuje 15, sto je i logicno, logicko 'ili' od 6, 7 i 8 daje 15.
Otkomentarisite [Flags] atribut iznad enumeracije.
Sada ce rezultat biti 'Six, Nine' sto je opet razumljivo.
FlagsAttribute 'forsira' enumeraciju da se ponasa kao bit flags pa pokazuje minimum kombinacija koje uparene daju 15.
Ali zasto je to 'Six, Nine' a ne 'Seven, Eight' ?

System.Windows.Forms.Keys ima [Flags] atribut, ali su u njoj sve vrednosti sa tastature poredjane od 0 do 254,
a Control, Shift i Alt su na kraju enumeracije:
Code:

        //
        // Summary:
        //     The SHIFT modifier key.
        Shift = 65536,
        //
        // Summary:
        //     The CTRL modifier key.
        Control = 131072,
        //
        // Summary:
        //     The ALT modifier key.
        Alt = 262144,

tako da logicko 'ili' nema problema da 'upari' sve kombinacije ova tri tastera sa jednom od 0-254 vrednosti.
Dakle, zasto je six | seven | eight - 'Six, Nine' a ne - 'Seven, Eight' ?

kopca
 
Odgovor na temu

DarkMan
Darko Matesic

Član broj: 20445
Poruke: 572
79.101.144.*

Jabber: DarkMan


Profil

icon Re: System.Windows.Forms.Keys enum i bitwise operatori.08.09.2008. u 11:33 - pre 190 meseci
Kada se ukljuci FlagsAttribute, metoda koja je zaduzena za konverziju vrednosti u string koristi hash tabelu za pronalazenje naziva enumeracija na osnovu vrednosti. Krajnji rezultat je tesko predvideti jer hash tabele ne odrzavaju redosled unosa (u ovom slucaju redosled enumeracija).

Uz pomoc NET Reflector-a sam pronasao metodu koja je zaduzena za konverziju:
Code:

private static string InternalFlagsFormat(Type eT, object value)
{
    ulong num = ToUInt64(value);
    HashEntry hashEntry = GetHashEntry(eT);
    string[] names = hashEntry.names;
    ulong[] values = hashEntry.values;
    int index = values.Length - 1;
    StringBuilder builder = new StringBuilder();
    bool flag = true;
    ulong num3 = num;
    while (index >= 0)
    {
        if ((index == 0) && (values[index] == 0L))
        {
            break;
        }
        if ((num & values[index]) == values[index])
        {
            num -= values[index];
            if (!flag)
            {
                builder.Insert(0, ", ");
            }
            builder.Insert(0, names[index]);
            flag = false;
        }
        index--;
    }
    if (num != 0L)
    {
        return value.ToString();
    }
    if (num3 != 0L)
    {
        return builder.ToString();
    }
    if (values[0] == 0L)
    {
        return names[0];
    }
    return "0";
}


 
Odgovor na temu

kopca

Član broj: 14307
Poruke: 118
82.117.202.*



Profil

icon Re: System.Windows.Forms.Keys enum i bitwise operatori.08.09.2008. u 11:59 - pre 190 meseci
Hvala na odgovoru. Uprkos tome vazi sledece:
Code:

(Test.Six | Test.Seven | Test.Eight) == (Test.Six | Test.Nine)
(Test.Six | Test.Seven | Test.Eight) == (Test.Seven | Test.Eight)

To moze da pomogne svima koji debugiraju nesto vezano za WinForms kao npr:
KeyDown, KeyPress, KeyUp ili ProcessCmdKey, ProcessKeyPreview metode u formama i user controlama.
Cesto parametri metoda ili property neke EventArgs klase sadrze Keys keyData sa kombinacijom tastera.
Watch verovatno poziva ToString() metodu za prikaz vrednosti, tako da to moze da bude zbunjujuce.
Primer je bas Keys enumeracija, FlagsAttribute i vrednosti koje nisu poredjane po stepenima dvojke.
Hvala jos jednom :)

kopca
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6042



+4631 Profil

icon Re: System.Windows.Forms.Keys enum i bitwise operatori.08.09.2008. u 13:44 - pre 190 meseci
Numericka vrednost ti je i dalje 15, sto mozes da vidis ako ga castujes u int, fora je samo u ispisu kao sto ti je DarkMan napomenuo, a i objasnjeno je lepo u msdn-u:

Citat:
If the FlagsAttribute is applied and there is a combination of one or more named constants equal to the value of this instance, then the return value is a string containing a delimiter-separated list of the names of the constants. Otherwise, the return value is the string representation of the numeric value of this instance


A i odgovor nije nepredvidiv, algoritam uvek krece od najvece enum vrednosti ka najmanjoj (ta hashed lista je sortirana) i za svaki bitwise match izvlaci ime i skracuje vrednost (oduzimanje je bitwise kao XOR operacija ako broj koji se oduzima ima sve bitove koje ima i broj od kojeg se oduzima). To je sasvim predvidivo i u skladu sa prirodom Flags enuma, ako imas dva razlicita broja veci od njih ili ima visi bit postavljen koji drugi nema (samim tim mora biti prisutan) ili ima vise jedinica na visim pozicijama od drugog, samim tim ce niz flegova biti kraci u ispisu jer se bitovi mogu kombinovati. U suprotnom bi svaki ToString bio sastavljen od (One, Two, Four, Eight, itd). Da si u enum listi imao Fifteen = 15, dobio bi kao izlaz "Fifteen".

Mada algoritam nije savrsen, funkcionise samo ako su sve vrednosti u enumu ili stepeni dvojke (1, 2, 4, ..) ili kombinacije postojecih enum bitova. Da si npr u taj enum dodao 13 (1101) koji nije OR kombinacija nijednog postojeceg elementa, kao izlaz bi dobio 15 numericki, posto ne bi imao sa cime da ukombinuje 13 (fali 2-ka)
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan, sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv… - Z.Đinđić
 
Odgovor na temu

[es] :: .NET :: System.Windows.Forms.Keys enum i bitwise operatori.

[ Pregleda: 2385 | Odgovora: 3 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.