Avatar billede Slettet bruger
18. maj 2008 - 20:31 Der er 33 kommentarer og
2 løsninger

Variabel der bliver sat ved anvendelse frem for oprettelse?

Hej eksperter!

Her kommer et lidt specielt spørgsmål, så jeg vil gøre mig umage med beskrivelser og forklaringer...

Jeg har brug for at have en variabel, der bliver sat ved anvendelse frem for oprettelse. Den letteste forklaring på anvendelsen er nok et eksempel:

class Test()
{
  public int A = 1;
  public int B = 2;
  public int C = A+B; // Der skal vel stå noget specielt her?
}
// Tests
Console.WriteLine(C.ToString); // 3
A = 2;
Console.WriteLine(C.ToString); // 4 og IKKE 3!

Hvordan er det muligt?
Avatar billede frand Nybegynder
18. maj 2008 - 20:42 #1
Du laver en property

public int C
{
  get{ return A+B; }
}
Avatar billede Slettet bruger
18. maj 2008 - 20:43 #2
Jeg er ikke sikker på, at det er muligt i mit tilfælde... Er der en anden løsning?
Avatar billede frand Nybegynder
18. maj 2008 - 20:46 #3
Hvorfor er det ikke muligt? Properties ER løsningen til sådanne situationer.
Avatar billede Slettet bruger
18. maj 2008 - 20:48 #4
Altså... Forklarer lige formålet. Jeg har en klasse med en masse instanser, der har forskellige måder at behandle nogle variable på. Eksempel:


// Klasse
class Klasse
{
  public static int A = 2;
  public static int B = 3;
  public int C;
  public Klasse()
  {
  }
}

// Instanser
Klasse Test1 = new Klasse();
Test1.C = Klasse.A + Klasse.B;
Klasse Test2 = new Klasse();
Test2.C = Klasse.A * Klasse.B;

// Tests
Test1.C // 5
Test2.C // 6
A = 4;
Test1.C // 7
Test2.C // 12
Avatar billede Slettet bruger
18. maj 2008 - 20:50 #5
Hov - der skulle
A = 4;
selvfølgelig være
Klasse.A = 4;
:)
Avatar billede Syska Mester
18. maj 2008 - 20:51 #6
igen ... som frand siger ... Properties

private int f_C;
public int C
{
  get{ return f_C; }
set{ f_C = value; }
}
Avatar billede Syska Mester
18. maj 2008 - 20:52 #7
public int C { get; get; } hvis du  bruger .NET 3.5
Avatar billede Slettet bruger
18. maj 2008 - 20:52 #8
?!?!?!??!?!?

Hvad?!
Kan du ikke lige sætte den ind i koden?
Avatar billede Slettet bruger
18. maj 2008 - 20:53 #9
Jeg bruger 3.5, ja.
Avatar billede frand Nybegynder
18. maj 2008 - 20:53 #10
I dette tilfælde, er det vel ikke en gang nødvendigt med en privat variabel til C

class Klasse
{
  public static int A = 2;
  public static int B = 3;

  public int C
  {
    get{ return A+B; }
  }

  public Klasse()
  {
  }
}

public static void Main(){
// Instanser
Klasse Test1 = new Klasse();
Klasse Test2 = new Klasse();

// Tests
Test1.C // 5
Test2.C // 6
A = 4;
Test1.C // 7
Test2.C // 12
Avatar billede Slettet bruger
18. maj 2008 - 20:56 #11
Prøv lige at se min kode igen... Det der holder ikke.
For Test1 er C=A+B, hvor C=A*B i Test2. Hvordan løser jeg så det?
Avatar billede frand Nybegynder
18. maj 2008 - 21:03 #12
Måske sådan:

// Klasse
class Klasse
{
  public int A = 2;
  public int B = 3;

  public enum Type{ Add, Multiply };
  private Type type;

  public int C
  {
    get{
      switch(type)
      {
    case Type.Add: return A+B;
        case Type.Multiply: return A*B;
        default:
          throw new System.ArgumentException("Ingen type");
      }
    }
  }

  public Klasse(Type type)
  {
    this.type = type;
  }
}

class program{

  public static void Main(){

    // Instanser
    Klasse Test1 = new Klasse(Klasse.Type.Add);
    Klasse Test2 = new Klasse(Klasse.Type.Multiply);

    // Tests
    System.Console.WriteLine(Test1.C); // 5
    System.Console.WriteLine(Test2.C); // 6
    Test1.A = 4;
    Test2.A = 4;
    System.Console.WriteLine(Test1.C); // 7
    System.Console.WriteLine(Test2.C); // 12
  }
}
Avatar billede Slettet bruger
18. maj 2008 - 21:08 #13
Nej, det duer ikke... Hvad så hvis jeg skal foretage andre operationer eller anvende andre variable end A og B? Der må være en anden løsning...
Avatar billede Slettet bruger
18. maj 2008 - 21:09 #14
Kan jeg ikke have alle de der

  public int C
  {
    get{ return A+B; }
  }

-linjer uden for selve klassedefinitionen?
Avatar billede Slettet bruger
18. maj 2008 - 21:10 #15
... eller måske

public int C;

i klassedefinitionen og

C
{
  get { return Noget+Lol+Omg+IfNotIAmReallyScrewed };
}

uden for?
Avatar billede frand Nybegynder
18. maj 2008 - 21:26 #16
Hvad skulle formålet være med at lægge C udenfor? Det antal forskellige matematiske udtryk for C, der skal være mulige, inkluderer du vel bare i klassen. Hvis det skal være muligt at ændre klassens type senere, så kan du bare gøre det muligt.

Ellers hedder det delegates, hvis du skal have C til at kalde en ekstern metode
Avatar billede Slettet bruger
18. maj 2008 - 21:43 #17
Altså... Jeg roder med lidt primitiv AI, og programmet skal således kunne sende forskellige beskeder til brugeren alt efter en række faktorer. De mulige beskeder oprettes som instanser af klassen (i tilfældene her 'Klasse') og har så hver i sær en række conditions for at kunne sendes. Disse conditions afgøres ved værdien af C, der i AI-programmet er af typen bool og netop beregnet ud fra AI'ens faktorer (og forskellig fra besked til besked).
Avatar billede driis Nybegynder
18. maj 2008 - 22:22 #18
Hvis du ikke vil have beregningen af C til at være placeret i klassen, kan du anvende en delegate, som du giver med i constructoren, som så, når C bliver brugt bliver kaldt.

Noget i retning af:
class Test
{
private Func<int,int,int> cImplementation;
public Test(Func<int,int,int> cImplementation)
{
  this.cImplementation = cImplementation;
}

public int A { get;set;}

public int B { get;set;}

public int C
{
  get { return cImplementation(A,B); }
}
}

Så kan du f.eks. lave en klasse test, hvor C returnerer summen af A og B ved at skrive:
Test t1 = new Test((a,b) => a + b);
(koden er ikke testet, men idéen skulle være tydelig nok)

Er det dét du har brug for ?
Avatar billede Slettet bruger
18. maj 2008 - 22:38 #19
Hmm... Måske. Hvad så hvis jeg har f.eks. 10 forskellige variable, jeg skal sammenligne?
Avatar billede aaberg Nybegynder
19. maj 2008 - 12:30 #20
Delegates er ikke en dårlig ide. Men brug anonyme delegates.

public delegate int Func();
class Test()
{
  public int A = 1;
  public int B = 2;
  public Func C;

  public Test()
  {
    C = new Func(delegate(){return A + B;});

    //eller:
    C = new Func(delegate(){return A * B;});
  }
}

Hvis du har 10 forskellige variabler:

int result = new Func(delegate(){return A + B + C + D...osv;});
Avatar billede Slettet bruger
19. maj 2008 - 12:35 #21
10 hænder er bedre end 8 :)
Jep, det er lige det, jeg skal bruge... Jeg tester det lige, når jeg har ædt mit mysli.
Avatar billede Slettet bruger
19. maj 2008 - 15:40 #22
SKAL Func() stå uden for klassen?
Avatar billede Slettet bruger
19. maj 2008 - 15:42 #23
Og et andet spørgsmål: Hvordan lavet jeg en parameter til delegate'ns conditions?
Avatar billede Slettet bruger
19. maj 2008 - 16:18 #24
Okay, jeg har ikke brug for en parameter, så her kommer et mere relevant spørgsmål:
C bliver af typen Func og ikke int. Hvordan får jeg returneret den resulterende int?

SkrivPaaSkaerm("Resulterende int: /*?!*/.ToString());

SkrivPaaSkaerm("Resulterende int: C.ToString()); virker som sagt IKKE.
Avatar billede Slettet bruger
19. maj 2008 - 16:18 #25
* RETTET *

Okay, jeg har ikke brug for en parameter alligevel, så her kommer et mere relevant spørgsmål:
C bliver af typen Func og ikke int. Hvordan får jeg returneret den resulterende int?

SkrivPaaSkaerm("Resulterende int: " + /*?!*/.ToString());

SkrivPaaSkaerm("Resulterende int: " + C.ToString()); virker som sagt IKKE.
Avatar billede driis Nybegynder
19. maj 2008 - 17:56 #26
C er nu en delegate, så den kan kaldes som en metode. Alt efter hvor mange parametre du har valgt; kan du så kalde C:
Console.WriteLine(C());
eller
Console.WriteLine(C(A,B));
Avatar billede Slettet bruger
19. maj 2008 - 18:18 #27

C = new Func(delegate(int omgkeklol){return A * B + omgkeklol;});
Console.WriteLine(C(27).ToString());
giver A*B+27?
Avatar billede aaberg Nybegynder
19. maj 2008 - 18:38 #28
C er af typen Func. en instans af typen Func kan kaldes som en metode og returnere en int.

Først skal Func-typen deklareres. Dette skal gøres uden for klassen:
public delegate int Func();

Inde i klassen har du en property du har kaldt C, som er af typen Func:
public Func C;

et eller andet sted sætter du C til at være en instans af typen Func. F.eks. i konstruktøren:
C = new Func(delegate(){return A + B;});

For at kalde C og få den til at returnere en integer gør du følgende:
int myInt = C();

Du kalder altså din property som om den var en metode. Når du kalder en delegate returnerer den typen som specificeres i deklarationen, i dette tilfælde en int.
Avatar billede aaberg Nybegynder
19. maj 2008 - 18:42 #29
En lille rettelse til det jeg lige har skrevet:

I koden jeg skrev i min sidste post, var C ikke en property men en variabel. For at få en property skrives:
public Func C{get;set;}
Avatar billede Slettet bruger
19. maj 2008 - 20:00 #30
Jamen, halløj, nu virker det vist :)
Tak for hjælpen... Kan jeg få en stak svar?
Avatar billede aaberg Nybegynder
19. maj 2008 - 21:37 #31
svar :-)
Avatar billede driis Nybegynder
19. maj 2008 - 22:37 #32
Svar.
Avatar billede Slettet bruger
19. maj 2008 - 22:50 #33
frand, buzzz
Avatar billede aaberg Nybegynder
27. maj 2008 - 22:08 #34
Kan vi lukke dette spørgsmål?
Avatar billede Slettet bruger
28. maj 2008 - 09:43 #35
Ja. Så skidt med de andre... Sorry :(
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