Avatar billede petermonielsen Nybegynder
16. april 2011 - 14:29 Der er 14 kommentarer og
2 løsninger

en bedre måde at styre konstanter med både et id og en værdi

public class ModelType
    {
        public int  Id { get; set; }
        public string Value { get; set; }
    }
public enum ModelTypeId { IkkeOplyst = 0, Koeleskab = 1 }
public static readonly ModelType[] modelTyper = new ModelType[]
            {
                new ModelType() { Id = (int)ModelTypeId.IkkeOplyst, Name = "Ikke oplyst" },
                new ModelType() { Id = (int)ModelTypeId.Koeleskab, Name = "Køleskab" }
            };
        public static ModelType GetModeltype(ModelTypeId modelTypeId)
        {
            for (int i = 0; i < modelTyper.Length; i++)
            {
                if (modelTyper[i].Id == (int)modelTypeId)
                    return modelTyper[i];

            }
            return new ModelType { Id = -1, Name = "Ukendt" };
        }

Ville bare lige høre om der findes en smartere måde at håndtere et array af konstanter som indeholder både et id og et navn?
Avatar billede heinzdmx Nybegynder
16. april 2011 - 14:33 #1
Måske med enums:
http://www.dotnetfunda.com/codes/code838-how-to-get-enum-value-in-csharp-.aspx

Der både kan have værdi og et tal som id.
Avatar billede janus_007 Nybegynder
16. april 2011 - 17:29 #2
Næh egentlig ikke :) Jeg vil nu ikke bruge enums til det, de er besværlige at arbejde med i den sammenhæng der.

Men jeg ville gøre sådan her istedet:

public class ModelType
    {
        public int  Id { get; set; }
        public string Value { get; set; }
    }
public enum ModelTypeId { IkkeOplyst = 0, Koeleskab = 1 }
public static readonly ModelType[] modelTyper = new ModelType[]
            {
                new ModelType() { Id = (int)ModelTypeId.IkkeOplyst, Name = "Ikke oplyst" },
                new ModelType() { Id = (int)ModelTypeId.Koeleskab, Name = "Køleskab" }
            };
        public static ModelType GetModeltype(ModelTypeId modelTypeId)
        {
            var type = modelTyper.Where(x => x.Id == (int)modelTypeId).SingleOrDefault();

            return type ?? new ModelType { Id = -1, Name = "Ukendt" };

           
        }
Avatar billede ulrikm Nybegynder
16. april 2011 - 20:09 #3
Kan et Dictionary ikke bruges?

enum ModelTypeId { IkkeOplyst = 0, Koeleskab = 1 }

Dictionary<ModelTypeId, ModelType> modelTyper = new Dictionary<ModelTypeId, ModelType>
{
  {ModelTypeId.IkkeOplyst, "Ikke oplyst"},
  {ModelTypeId.Koeleskab, "Køleskab"}
};
Avatar billede arne_v Ekspert
17. april 2011 - 03:17 #4
Designet er helt forkert.

Det duer ikke at have en type med 2 værdier som skal have en bestemt relation men denne relation er ikke sikret via typen.

Saa:
* drop ModelType
* brug enum ModelTypeId (enum er det helt rigtige til den slags) overalt i koden
* lav en static helper method eller en extension method når der i forbindelse med output skal vises en tekst
Avatar billede janus_007 Nybegynder
17. april 2011 - 11:54 #5
Ja designet er forkert i det lille stykke kode, men jeg tror det er de færreste der tænker at det lille stykke kode skal bruges til andet end spørgsmålet :)

Hvis koden afspejler virkeligheden og dit eneste behov er en keyvalue lign. type så brug en keyvalue :)

KeyValuePair<int, string>

Eller hvorfor ikke bare bruge enum'en direkte?

Ak ja.. der er mange muligheder, når alt kommer til alt er det nok fordi spørgsmålet ikke er særligt præcist stillet ;-)

Et array af konstanter er lidt besynderligt :)
Avatar billede petermonielsen Nybegynder
17. april 2011 - 12:52 #6
tak for svarene.

til arne_v : kan du give et eksempel på en sådan extension metode?

Til janus: hvad mener du med at bruge enum'en direkte ? - hvordan kan jeg gemme og printe tekst med eksempelvis mellemrum i en enum?
Avatar billede arne_v Ekspert
17. april 2011 - 16:44 #7
Det er ligegyldigt om der er 100 linier eller 1 million linier kode. Konceptet med to fields der skal matche uden at det sikres af koden er daarligt.
Avatar billede arne_v Ekspert
17. april 2011 - 16:44 #8
Demo af extension metode:

using System;

namespace E
{
    public enum Classic { HelloWorld, FooBar }
    public static class EnumPrint
    {
        public static string ToReadableString(this Classic e)
        {
            switch (e) {
                case Classic.HelloWorld:
                    return "Hello world";
                case Classic.FooBar:
                    return "Foo bar";
                default:
                    throw new Exception("Unexpected enum value for Classic");
            }
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            Classic e = Classic.FooBar;
            Console.WriteLine(e.ToReadableString());
            Console.ReadKey();
        }
    }
}
Avatar billede janus_007 Nybegynder
17. april 2011 - 20:30 #9
ahh.. var ikke klar over at det skulle bruges ifb. med print, men okay. Tjaa jeg ville nok lave det på samme måde som Arnes... eller måske noget alá:

[DIV]
public enum ModelTypeId { IkkeOplyst = 0, Koeleskab = 1 }

    public class ModelHelper
    {
        public Dictionary<ModelTypeId, string> KVP{get; set;}

        public ModelHelper()
        {
            KVP.Add(ModelTypeId.IkkeOplyst, "Ikke oplyst");
            KVP.Add(ModelTypeId.Koeleskab, "Køleskab");
        }

    }

    public class Foo
    {
        public Foo()
        {
            var print = new ModelHelper().KVP[ModelTypeId.Koeleskab];
        }
    }
[/DIV]

Hvis man kun skal bruge en beskrivelse på sin enum, så er det en mulighed at bruge Description attributten fra ComponentModel, altså:
[DIV]
using System.ComponentModel;

namespace ConsoleApplication7
{
    public enum ModelTypeId
        {
            [Description("Ikke Oplyst")]
            IkkeOplyst = 0,
            [Description("Køleskab")]
            Koeleskab = 1 } 

    public class TestMe
    {
        public TestMe()
        {
            var print = ModelTypeId.Koeleskab.EnumDescription();

        }
    }

    public static class EnumExtensions
    {
        public static string EnumDescription(this ModelTypeId value)
        {
            System.Reflection.FieldInfo fi = value.GetType().GetField(value.ToString());

            var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(
                typeof(DescriptionAttribute),
                false);

            return attributes != null &&
                  attributes.Length > 0
                      ? attributes[0].Description
                      : value.ToString();
        }
    }

}

[/DIV]
Avatar billede arne_v Ekspert
19. april 2011 - 03:36 #10
Dictionary loesningen har praecis samme problem som den originale - der er ikke noget i koden som sikrer konsistens mellem de to vaerdier.

Description er derimod en glimrende maade at goere det paa. Det sikrer en konsistens og samler det hele i en enkelt type.
Avatar billede petermonielsen Nybegynder
19. april 2011 - 08:05 #11
tak for hjælpen. Jeg synes at janus og arne skal dele pointene. Lægger i et svar?
Avatar billede petermonielsen Nybegynder
19. april 2011 - 08:25 #12
mht. Description løsningen - hvordan laver jeg et foreach loop igennem enum'et ?
Avatar billede petermonielsen Nybegynder
19. april 2011 - 08:29 #13
foreach (string name in Enum.GetNames(typeof(ModelTypeId)))
{
}

kunne benyttes - men hvordan får jeg adgang til at kalde EnumDescription() ?
Avatar billede petermonielsen Nybegynder
19. april 2011 - 08:36 #14
foreach (ModelTypeId modelTypeId in Enum.GetValues(typeof(ModelTypeId)))
        {
int val = (int)modelTypeId;
string description = modelTypeId.EnumDescription();
        }

GetValues var løsningen. bare se bort fra det sidste spørgsmål.
Avatar billede arne_v Ekspert
19. april 2011 - 18:01 #15
svar fra mig
Avatar billede janus_007 Nybegynder
19. april 2011 - 19:05 #16
:)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester