Avatar billede mikkelbm Nybegynder
11. august 2006 - 10:07 Der er 19 kommentarer og
1 løsning

Problemer med enums

Hej

Jeg er løbet ind i en sjov situation med enums i .NET. Eller også er det bare mig der misforstår noget.

Jeg har en enum i én assembly:

public enum MyEnum
{
  Enum1,
  Enum2,
  Enum3
}

Og en anden assembly der bruger denne enum:

Something som = SomeClass.GetSomething (MyEnum.Enum1);
Nu er som = MyEnum.Enum1;

Problemet opstår i det øjeblik hvor jeg laver min enum om til:

public enum MyEnum
{
  Enum0,
  Enum1,
  Enum2,
  Enum3
}

Uden igen at compile den assembly der bruger min enum.

Something som = SomeClass.GetSomething (MyEnum.Enum1);
Nu er: som = MyEnum.Enum0;

Og det er jo ikke det jeg vil.

Så mit spørgsmål går på om ikke det er muligt at reorder mine enums, når først en client har compilet op mod dem?

Jeg ved godt jeg kan give mine enums værdier, som sikkert vil løse problemet, men jeg kunne godt tænke mig friheden bare at kunne sortere/gruppere mine enums uden at værdierne vil stå usorteret.
Avatar billede mikkelbm Nybegynder
11. august 2006 - 10:09 #1
Jeg faldt lige over denne side:

http://jcp.org/aboutJava/communityprocess/jsr/tiger/enum.html

For den nye Java version.

Og det jeg egentlig efterspørger er pkt. 4:

Typesafe constants aren't compiled into clients, so you can add, reorder or even remove constants without the need to recompile clients.


Kan det lade sig gøre i .NET ?
Avatar billede akempff Nybegynder
11. august 2006 - 11:57 #2
Jeg vil tro at du har copy local sat til true under din reference property.  Det vil sige at den assembly der benytter din enum, har en kopi af din dll ligende og det er så den den benytter, hvorfor dine ændringer ikke slår igennem.
Kopier din nye dll over og overskriv, så burde der ikke være nogle problemer.
Dette kan eventuelt laves til et post-compile script, da det jo skal gøres hver gang du kompilere din enum assembly.  Du kan også sige copy local = false, men så får du hurtigt problemer med hvem der har fat i iden.
Avatar billede mikkelbm Nybegynder
11. august 2006 - 12:12 #3
Det er ikke det der er problemet. Jeg har faktisk et post-compile script, som kopierer mine dll'er.
Avatar billede mikkelbm Nybegynder
11. august 2006 - 12:14 #4
Det jeg efterspørger er om enums i .NET er typesafe på samme måde, som de vil blive i den nye java-version.

Blandt andet skrives der i det link jeg har refereret til:

"it has many advantages over the enum facilities in C, C++, C# and Pascal."

Så jeg er begyndt at tvivle på, at det kan lade sig gøre uden at give dem værdier.
Avatar billede mikkelbm Nybegynder
11. august 2006 - 12:15 #5
Ideen er jo netop at jeg ikke altid har mulighed for at compile de enkelte client-dll'er når jeg har ændret i min enum.
Avatar billede mikkelbm Nybegynder
11. august 2006 - 12:15 #6
Ideen ~ problemet

:)
Avatar billede akempff Nybegynder
11. august 2006 - 13:00 #7
Ja ok, jeg tror jeg begynder at forstå problemet nu.

Jeg har lige lavet en test, med en enum:
Først: public enum EnumTest{test1,test2,test3}
dernæst: public enum EnumTest{test0,test1,test2,test3}

i sin egen assembly og et program der benytter denne assembly:

int t = (int)EnumTest.EnumTest.test2;
            Console.WriteLine(t);
            Console.ReadLine();
Avatar billede akempff Nybegynder
11. august 2006 - 13:05 #8
hov...var ikke færdig (fumlefingre).

Ved kørsel af main og brug af første enum assembly var resultatet 1.
Ved næste kørsel med ny assembly var resultatet 2.

Så det var jo som forventet. Men jeg tror ikke du kan komme uden om at enum værdien ændrer sig uden at give dem fastlagte værdier. Men det burde jo heller ikke gøre noget når det jo er den rigtige enum man får fat i med f.eks. EnumTest.test2
Avatar billede akempff Nybegynder
11. august 2006 - 13:17 #9
Det er noget vrøvl jeg skriver.  Hvis jeg ikke recompiler så får jeg samme fejl som du beskriver.
Avatar billede arne_v Ekspert
11. august 2006 - 13:22 #10
problemet er at .NET enum grundliggende er en int og at du ved sammenligning af
int sammenligner int værdien

(i Java er en enum grundliggende et objekt om man sammenligner om objekt referencen
er den samme)
Avatar billede arne_v Ekspert
11. august 2006 - 13:23 #11
prøv for sjov skyld at køre denne kode:

using System;

namespace E
{
    public enum Fruits { Apples, Oranges, Grape };
    public enum Cars { Ford, Toyota, Mercedes };
    public enum Colors { Red, Green, Blue };
    public class TestClass
    {
        public static void Main(string[] args)
        {
            Fruits fru = Fruits.Grape;
            Cars car = Cars.Mercedes;
            Colors col = (Colors)((int)fru / (int)car);
            Console.WriteLine(col);
        }
    }
}
Avatar billede akempff Nybegynder
11. august 2006 - 13:32 #12
Det er meget mystisk hvorfor de ændringer ikke slår igennem i dllen.
Det må vel næsten være noget .net caching eller et eller andet?
Avatar billede mikkelbm Nybegynder
11. august 2006 - 13:38 #13
Ja, okay... Så giver det lidt mening. Så faktum er, at man ikke kan typesikre sine enums uden at fastsætte værdier for dem?

Smid et svar - begge to.
Avatar billede akempff Nybegynder
11. august 2006 - 13:47 #14
Ellers tak, jeg undlader at svare. Det har vist skabt mere forvirring end gavn :)
Avatar billede mikkelbm Nybegynder
11. august 2006 - 17:32 #15
Det er okay :)

Arne, du har til i aften til at svare - ellers går der 2 uger inden jeg igen er tilbage :)
Avatar billede arne_v Ekspert
11. august 2006 - 18:49 #16
her er et simpelt recreation eksempel:

C:\>type v1.cs
public enum V
{
    X = 1
}

C:\>type v2.cs
public enum V
{
    X = 2
}

C:\>type test.cs
using System;

public class Test
{
    public static void Main(string[] args)
    {
        Console.WriteLine((int)V.X);
    }
}

C:\>csc /t:library /out:v.dll v1.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.6001.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.


C:\>csc /t:exe /r:v.dll test.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.6001.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.


C:\>test
1

C:\>csc /t:library /out:v.dll v2.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.6001.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.


C:\>test
1

C:\>csc /t:exe /r:v.dll test.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.6001.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.


C:\>test
2
Avatar billede arne_v Ekspert
11. august 2006 - 18:57 #17
og haelder man test.exe gennem reflector + disassembler faaar man:

public static void Main(string[] args)
{
      Console.WriteLine(2);
}

enum's bliver til int konstanter i den compilede kode

og derfor erdet jo klart at andringerne ikke slaar igennem
Avatar billede arne_v Ekspert
11. august 2006 - 18:57 #18
og et svar
Avatar billede mikkelbm Nybegynder
11. august 2006 - 19:05 #19
Ja, det var netop det med at bindingen skete compile-time jeg ikke var sikker på. Og da det er sådan, er resultatet jo også klart...
Avatar billede akempff Nybegynder
11. august 2006 - 20:17 #20
Jamen men så blev man så meget klogere. :)
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