Vítejte na blog.vyvojar.cz Přihlásit | Registrovat | Pomoc

Vlko napísal ...

.. mostly harmless ...
StringEnum podľa vlka

Dnes len tak pri bežnom dennom kódení vyvstala z môjho kódu interná potreba textového enumeration typu (ach tá angličtina, vôbec mi do hlavy nejde rozumný slovenský preklad).

Nuž a ako to už bežne býva, keď niečo nie je v systéme  na pomoc rýchlo prichádza google a v ňom zopár článkov (String Enumerations in C#, How do you convert a string into an enum?, Enum With String Values In C#, atď) popisujúci tieto základné spôsoby:

  1. Enum s konverziou na string - ja ale potrebujem ukladať pre jednotlive hodnoty kód, čo potom v zdrojákoch nevyzerá najlepšie.
  2. Konštanty - super použitie, avšak chýba kontrola hodnoty (vlastne pri pretypovaní ju nemá ani enum).
  3. Static readonly - tu už je možné použiť ako hodnotu triedu aj s kontrolou na hodnotu, nevýhodou ale je nemožnosť použitia v switch.
  4. Atribúty s extensions metódou - pekné riešenie, akurát reflexia je vždy brzdou aplikácie, extensions metódy mi nikdy nevoňali a pri pretypovaní by teoretický mohli vzniknúť ťažko odhaliteľné chyby.

Všetko to proste viedlo k jednému záveru. Svet potrebuje ešte jedno riešenie a to podľa vlka:). Najskôr teda požiadavky:

  • použitie v swith príkaze, teda hodnota musí byť const
  • aspoň jednoduchá kontrola na vkladanú hodnotu
  • a čo najjednoduchšie použitie

Základ bude tvoriť trieda obsahujúca hodnoty ako konštanty:

    public class StringEnum 

    {

        public const string SomeValue = "val1";

 

        public const string OtherValue = "val2";

 a umožňovať by mala nasledujúce konštrukcie:

            StringEnum value1 = StringEnum.OtherValue;

            StringEnum value2 = StringEnum.SomeValue;

            switch (value1)

            {

                case StringEnum.OtherValue:

                    Console.WriteLine(value1);

                    break;

                case StringEnum.SomeValue:

                    Console.WriteLine(value1);

                    break;

            }

            bool compare = value1 == value2;

            compare = value1 == StringEnum.OtherValue;

Aby som zabezpečil čo najväčšiu znovupoužiteľnosť, vytvoril som si bázovú triedu, ktorá bude robiť všetko to, čo netreba kopírovať medzi projektami. Teda obsahuje hodnotu inštancie enumu a v protected konštruktore ošetruje vkladanú hodnotu, pomocou výnimky StringEnumValueException a abstraktnej funkcie GetValidValues, ktorá vracia zoznam platných hodnôt

    public abstract class BaseStringEnum

    {

        /// <summary>

        /// Gets the valid values.

        /// </summary>

        /// <returns>Should return valid string values for this string enum.</returns>

        protected abstract List<string> GetValidValues();

        /// <summary>

        /// Gets or sets the value.

        /// </summary>

        /// <value>The value.</value>

        public string Value { get; private set; }

 

        /// <summary>

        /// Initializes a new instance of the <see cref="StatisticsTypeEnum"/> class.

        /// </summary>

        /// <param name="value">The value.</param>

        protected BaseStringEnum(string value)

        {

            // test if value is valid

            if (!GetValidValues().Contains(value))

            {

                throw new StringEnumValueException(this.GetType(), value);

            }

            Value = value;

        }

Potiaľ je to jednoduché nasleduje pár jednoduchých overridov, prvý na textovú reprezentáciu projektu:

        public override string ToString()

        {

            return Value;

        }

a veľmi dôležitá funkcia pre porovnávanie dvoch objektov, ktorá nám zabezpečí, aby sme, keď to je potrebné, porovnávali len textovú podobu objektu

        public override bool Equals(object obj)

        {

            // compare with string

            if (obj is string)

            {

                return string.Equals(obj, Value);

            }

            // compare with same string enum

            else if ((this.GetType() == obj.GetType()) && (obj is BaseStringEnum))

            {

                return string.Equals((obj as BaseStringEnum).Value, Value);

            }

            // call base compare

            return base.Equals(obj);

        }

a hlavne podstatná finta, ktorá nám zabezpečí implicitnú konverziu nášho string enumu na string

        public static implicit operator string(BaseStringEnum stringEnum)

        {

            if (stringEnum == null)

            {

                return null;

            }

            return stringEnum.Value;

        }

Na základnú triedu to úplne stačí, zostáva nám implementovať potomka, tu je potrebné definovať vlastné hodnoty enumu a abstraktnú funkciu GetValidValues, ktorá vracia povolené hodnoty pre náš enum

    public class StringEnum : BaseStringEnum

    {

        public const string SomeValue = "val1";

 

        public const string OtherValue = "val2";

 

        /// <summary>

        /// Gets the valid values.

        /// </summary>

        /// <returns>

        /// Should return valid string values for this string enum.

        /// </returns>

        protected override List<string> GetValidValues()

        {

            return new List<string> { SomeValue, OtherValue };

        }

privátny konštruktor, ktorý zabezpečí naplnenie hodnoty a znemožní vytvorenie inštancie z kódu

        private StringEnum(string value) : base (value)

        {

        }

a aby to všetko pekne fungovalo, tak ako má, tak tá najdôležitejší časť celého riešenia a to implicitná konverzia zo stringu na náš StringEnum typ

        public static implicit operator StringEnum(string value)

        {

            return new StringEnum(value);

        }

To je všetko, takáto trieda sa už potom normálne používa ako enum, možno sa ešte hodí označiť base triedu pomocou Serializable atribúta, ale to už nechám na každého uváženia a potrieb.

A nakoniec zostávajú už len zdrojové kódy StringEnum source a nevýhody:

  • Aj keď to simuluje enum funkčnosť enum to nikdy nebude:)
  • chýba default hodnota, tak ak má niekto nápad ako toto ošetriť, teda konverziu null hodnoty na default hodnotu

 

 

 

 

Posted: 8. října 2008 13:29 by vlko
Vedeno pod:

Komentář

peter napsal:

K tomu: "...konverzia null hodnoty na default hodnotu", myslel si tym nullable?

Pretoze to pokial viem nepojde kedze 'BaseStringEnum' je classa a nie 'value type', napr struct.

# listopadu 28, 2008 8:27

vlko napsal:

to peter: myslel som tym to druhe a veruze viem, ze to nejde, overridnut default v triede nie je mozne, ale vzdy moze niekoho napadnut workaround;)

# prosince 9, 2008 11:00

Jhonatan napsal:

Knwoldege wants to be free, just like these articles!

# března 29, 2012 4:07

zddugsl napsal:

# března 29, 2012 8:43

qswrrwvuld napsal:

CMjMxJ , [url=http://jekepxvbhqmp.com/]jekepxvbhqmp[/url], [link=http://xjxaxoenopvq.com/]xjxaxoenopvq[/link], http://omwgaokrdjca.com/

# března 30, 2012 8:35

tcrjsc napsal:

# března 31, 2012 9:53

akxqucosby napsal:

Iwn4pa , [url=http://qteomhsxfpko.com/]qteomhsxfpko[/url], [link=http://bevsbzwlhpok.com/]bevsbzwlhpok[/link], http://euoekiqzphun.com/

# dubna 1, 2012 8:10

buy kamagra 100 mg oral jelly napsal:

kamagra oral jelly usage

[url=http://kamagrabst.com/]kamagra forum[/url]

kamagra oral jelly wirkungsweise

<a href="http://kamagrabst.com/">http://kamagrabst.com/</a>

kamagra 100mg oral jelly usa

http://kamagrabst.com/

kamagra store reviews

# dubna 3, 2018 18:44

buy kamagra 100mg napsal:

ajanta kamagra 100 chewable tablet

[url=http://kamagrabst.com/]kamagra oral jelly 100mg online[/url]

kamagra store erfahrung

<a href="http://kamagrabst.com/">kamagra soft tablets 100mg</a>

kamagra store coupon

http://kamagrabst.com/

erfahrungsbericht kamagra oral jelly wirkung

# dubna 5, 2018 6:00

kamagra 100 mg oral jelly napsal:

kamagra us website

<a href="http://kamagrabst.com/">kamagra">http://kamagrabst.com/">kamagra oral jelly wirkung bei frauen</a>

kamagra store

[url=http://kamagrabst.com/]kamagra oral jelly wirkungsdauer[/url]

kamagra 100mg tablets side effects

http://kamagrabst.com/

kamagra 100mg chewables

# dubna 6, 2018 11:48

buy kamagra 100 mg oral jelly napsal:

kamagra oral jelly 100mg reviews

[url=http://kamagrabst.com/]kamagra oral jelly come si usa[/url]

kamagra forum srpski

<a href="http://kamagrabst.com/">the kamagra store coupon</a>

kamagra oral jelly for sale in usare

http://kamagrabst.com/

kamagra shop erfahrungen 2016

# dubna 7, 2018 11:28

StephenTiedo napsal:

kamagra 100mg chewable tablets

<a href="http://kamagraonl.com/">buy">http://kamagraonl.com/">buy kamagra online</a>

kamagra 100mg tablets usage

[url=http://kamagraonl.com/]buy kamagra online[/url]

kamagra oral jelly for sale in usare

http://kamagraonl.com/

kamagra gel forum hr

# května 9, 2018 3:46

Michaeltah napsal:

kamagra oral gel

<a href="http://kamagraonl.com/">buy">http://kamagraonl.com/">buy kamagra 100mg</a>

kamagra 100mg oral jelly suppliers indianapolis in

[url=http://kamagraonl.com/]kamagra 100mg[/url]

kamagra oral jelly for sale in usage

http://kamagraonl.com/

kamagra now reviews

# května 9, 2018 14:53

Marionrob napsal:

kamagra kopen in de winkel utrecht

<a href="http://kamagraonl.com/">kamagra">http://kamagraonl.com/">kamagra 100mg</a>

kamagra usa next day shipping

[url=http://kamagraonl.com/]kamagra 100mg[/url]

kamagra 100mg tabletta

http://kamagraonl.com/

kamagra jelly india for sell

# května 10, 2018 7:58
Vytvoření nového komentáře

(povinný) 

(povinný) 

(nepovinný)

(povinný) 

Opiš čísla, která vidíš na obrázku:

Upozornění na nové komentáře

Pokud chčeš dostávat upozornění emailem na změny u toho příspěvku,tak se zaregistruj zde.zde

Odebírat komentáře k tomuto příspěvku pomocí RSS

Vyvojar.cz na prodej!