Avatar billede thjal Nybegynder
01. maj 2007 - 16:06 Der er 17 kommentarer og
1 løsning

simple typer i C# og hvordan laver man sine egne typer?

Okay her er noget jeg ikke forstår:

I C# anskuer man en simpel type som for eksemple en int som værende et objekt (den har ihvertfald nogle methods når man skriver "." efter en erkleret integer. Det er også fint nok. At man ikke kan lave en klasse der er nedarvet af den type er så lidt ærgeligt men OK her er noget nyt (i hvert fald i forhold til C++) som hedder "sealed". OK fin nok. MEN her kommer så mit spørgsmål: hvordan kan det så være at jeg IKKE kan lave en ny klasse som kan opføre sig på samme måde som en int? VB6 havde en feature der hed "default", men den "mangler" så for at kunne lave dette nummer.
Og så det helt umulige tillægsspørgsmål: hvordan skal klassen rInt laves for at man kan komme til at skrive følgende syntax?

public class test
{
private rInt myrInt = 0;
public test()
{
this.myrInt = 10;
}
}
Avatar billede arne_v Ekspert
01. maj 2007 - 16:17 #1
en int er en struct ikke en class

og du blive rnok noedt til at bruge:

private rInt myrInt = new rInt(0);
Avatar billede jens_klinting Nybegynder
01. maj 2007 - 21:11 #2
Du kan evt. også kaste dig ud i operator overloading på din rInt-struct. Desværre kan man ikke overloade assignment jvf. arne_v.

Du kan finde mere om overloading her: http://www.csharphelp.com/archives/archive135.html

Mvh.
Jens
Avatar billede thjal Nybegynder
02. maj 2007 - 10:48 #3
OK så en int er en struct og ikke en klasse - men hvordan kan det så alligevel være at jeg ikke kan lave en struct hvis instance "opfører" sig og lader sig manipulere som f.eks en int?
- Jens tak for kommentaren men den gav ikke meget værdi da jeg er helt med på operator overolading.
Det jeg i princippet gerne vil undgå er at skrive myrInt.x = 10 men istedet vil jeg gerne skrive myrInt = 10.
I dette tilfælde ville x naturligvis være en member af structen rInt.
Avatar billede thjal Nybegynder
02. maj 2007 - 10:58 #4
lige en tanke kan det gøre ved at lave en enum?
Avatar billede arne_v Ekspert
02. maj 2007 - 17:06 #5
int v = 10;

virker fordi 10 er en int

du kan ikke lave

rInt myrInt = 10;

fordi 10 stadig er en int og C# ikke har support for rInt konstanter
Avatar billede thjal Nybegynder
02. maj 2007 - 20:57 #6
arne_v smid et svar så får du pointene
- men det vil altså sige at en int er ikke som sådan en struct? Jeg ved godt at det jeg efterspørger heller ikke kan gøres i C++, men det var jo muligt med VB6.
Avatar billede arne_v Ekspert
02. maj 2007 - 21:24 #7
svar
Avatar billede arne_v Ekspert
02. maj 2007 - 21:24 #8
jo - int er en struct

men forskellen er at C# kan generere konstanter af den type

jeg mener faktisk godt at man kan lave den slags i C++ med passende constructor og
assignment operator overload
Avatar billede thjal Nybegynder
02. maj 2007 - 21:49 #9
nå ja det er det der er forskellen... c++ kan lave en operator overload med = som C# ikke kan. Glemte det lige.
Avatar billede kodehoved Nybegynder
02. maj 2007 - 22:37 #10
C# arbejder med to slags typer: value type og reference types. Kort fortalt er value types letvægtstyper, der allokeres på stakken mens reference types er "tungere" i den forstand at de allokeres på heapen. C# kan selv konvertere frem og tilbage mellem value og reference types via det man kalder boxing/unboxing.

For at svare på dit spørgsmål, kan du ikke lave en klasse (altså en reference type), der opfører sig som int (som er en value type), men du kan lave en struct, der har (næsten) samme opførsel som en int.

Jeg har skrevet en <a href="http://kodehoved.dk/?p=25">længere smøre om C# typer</a> som forklare flere af detaljerne. Håber du kan bruge svaret.
Avatar billede thjal Nybegynder
25. maj 2007 - 22:31 #11
OK nu er jeg vist blevet lidt klogere og har som sådan fundet løsningen på mit problem (mener jeg) Jeg vil lige skrive det her og høre om der er nogen der mener at der er fælder i det her?

    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            MyInt32 tst = new MyInt32();
            MyInt32 tst2 = new MyInt32();
            MyInt32 tst3 = 15;

            MyInt32 myint1, myint2, myint3;
            myint1 = myint2 = myint3 = 64;
            Console.WriteLine(myint1);
            Console.WriteLine(tst3);
            int x = 11;

            tst3 = 14;
            Console.WriteLine(tst3);
            tst = (MyInt32)x;
            Console.WriteLine(tst);
            tst2 = 22;
            Console.WriteLine(tst2);
            tst = tst + tst2;
            Console.WriteLine(tst);
            tst = tst2;
            Console.WriteLine(tst);

            Console.Read();
        }   
    }
    public struct MyInt32
    {
        private Int32 iInternal;
       
        public override string ToString()
        {
            return string.Format ("{0}",iInternal);
        }
        public static implicit operator MyInt32(int iValue)
        {
            MyInt32 temp = new MyInt32();
            temp.iInternal = iValue;
            return temp;
        }
        public static MyInt32 operator + (MyInt32 t1, MyInt32 t2)
        {
            MyInt32 temp = new MyInt32();
            temp.iInternal = t1.iInternal + t2.iInternal;
            return temp;
        }
    }

Koden compilere (.NET 2.0) og exekverer som jeg forudser. Det vil sige jeg får tildelt de værdier som jeg ønsker og der hvor jeg skriver tst, tst2 og tst3 ud kommer værdien og ikke typen. Det kommer selvfølgelig af at jeg overrider ToString().
Selvfølgelig skal alle operatorerne overrides...

Men som sagt er der her nogen kommentarer (pitfalls?)- så vil jeg meget gerne have dem.
Avatar billede arne_v Ekspert
27. maj 2007 - 02:34 #12
En implicit conversion operator er jo faktisk lige så god som en assignment operator.

Jeg tror at det er en glimrende løsning.
Avatar billede kodehoved Nybegynder
27. maj 2007 - 08:33 #13
Hej igen

Jeg er ikke helt sikker på, hvad du vil med ovenstående, men her er i hvert fald et par kommentarer. Håber du kan bruge dem.

- Du behøver ikke at caste x i "tst = (MyInt32)x;" da du har overloaded implicit cast til int.
- Hvis du laver en sådan struct, bør du lave den immutable - dvs. du skal ikke kunne ændre en instans når den er oprettet. Du kan jo heller ikke ændre værdien af en int (du får en nu instans hver gang).
- "MyInt32 tst = new MyInt32();" er en meget bøvlet måde at skrive "MyInt32 tst = 0" - (værdityper nulstilles ved oprettelse, så default er 0 for din type).
- Du kan gøre koden væsentlig kortere ved at lave en constructor, der tager en int:

    public struct MyInt32 {
        private Int32 iInternal;
        public MyInt32(int value) {
            iInternal = value;
        }
        public override string ToString() {
            return string.Format("{0}", iInternal);
        }
        public static implicit operator MyInt32(int iValue) {
            return new MyInt32(iValue);
        }
        public static MyInt32 operator +(MyInt32 t1, MyInt32 t2) {
            return new MyInt32(t1.iInternal + t2.iInternal);
        }
    }
Avatar billede arne_v Ekspert
28. maj 2007 - 04:46 #14
Man ændrer faktisk værdien af en int.
Avatar billede kodehoved Nybegynder
28. maj 2007 - 09:41 #15
Doh! Ja, jeg mente en string. Jeg tror jeg havde skrevet int lidt for mange gange i det indlæg.
Avatar billede thjal Nybegynder
28. maj 2007 - 15:52 #16
kodehoved: tak for dit indlæg - jeg kan godt se din simplificering af min kode og den er smart. Jeg vil nok også implementere constructoren der tager en int (det er smart nok at kunne). Det jeg vil i princippet er at lave en "type" af MyInt32 som "aggere" på samme måde som en int. Dvs. når jeg i min kode skriver f.eks.
MyInt32 myint1, myint2;
myint1 = 12;
myint2 = 6;
myint1 /= myint2;
Console.Write(myint1);
- så skulle den gerne komme ud med 2 på konsollen. Som jeg skrev foroven vil jeg selvfølgelig operator overloade alle operatorer og sammenlignings tingene (kan ikke lige huske hvad det hedder under een hat: >=, <=, == og !=).
Så igen tak for kommentaren - den er værdsat.
Avatar billede kodehoved Nybegynder
29. maj 2007 - 08:54 #17
Jeg kan godt se, hvad du forsøger, men hvorfor vil du lave din egen Int32?
Avatar billede thjal Nybegynder
29. maj 2007 - 20:10 #18
For at tilføre flere metoder og private variabler til inten. Feks. maks og min værdier som skal overholdes + lidt andre forskellige ting...
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