Avatar billede c-sharp Nybegynder
23. marts 2006 - 15:59 Der er 15 kommentarer og
1 løsning

Spørgsmål til pæn kode i asp.net

Jeg har nogle spørgsmål til hvordan man gør tingene pænest.

Hvis jeg har nogle globale variabler som skal huskes efter postback, hvordan laver jeg sådan nogle. Skal jeg bruge viewstate og initialisere en global variabel efter hvert postback, eller skal jeg bare bruge viewstate direkte eller hvad?

Når jeg i en metode modtager nogle variabler skal jeg så bare bruge disse i metoden eller skal jeg ligge dem over i nogle nye variabler:

eks. 
public void test(string _hej, int tal)
{
  string hej = _hej;
  int tal = _tal;
}


Bør man ikke skrive en masse kode i en event, men istedet ligge den kode i seperate metoder?
Avatar billede snepnet Nybegynder
23. marts 2006 - 18:17 #1
hej c#

hvis dine globale variable er "globale" for din session - kan du lægge dem der (i session). benytter du asp.net 2.0 kan du udnytte profiles til den slags også.
hvis de virkelig er globale - kan du lægge dem i Cache, Application hvis du ønsker at holde dem i memory - eller arbejde på direkte direkte i en database ell.
det er rigtigt at der er mange relaterede muligheder, men det skulle gerne være sådan, at der er en mulighed der er bedre end de andre for en given opgave :o)

mht. til det her:
public void test(string _hej, int tal)
{
  string hej = _hej;
  int tal = _tal;
}

så er svaret nok lidt mere omfattende end du havde forestillet dig.

en int er en value-type, hvilket bla. betyder at du - når du benytter den som parameter i en metode - får en kopi af den.
du kan derfor gøre med den hvad du vil - og hvis du har lyst til at lave endnu en kopi af den - er du velkommen.

alle de simple typer (int, bool mv.) + structs og enum's er valuetyper - og du kan entydigt kende dem ved, at de alle ultimativt arver fra System.ValueType.

en string er derimod en referencetype, men da den er en lidt speciel en af slagsen - bruger jeg lige en anden for en kort bemærkning (skal nok komme tilbage til det med strings).

men... lad os tage et eksempel:

du har en klasse:
public class Person
{
...
}

og du vil gerne bruge personobjekter som parametre på en metode:

// et eller andet sted
Person p = new Person();
GetPersonsCprNumber(p);

string GetPersonsCprNumber(Person personInstance)
{
  ...
}

det der sker i ovenstående tilfælde er nøjagtig det samme... der bliver overført en kopi af p - Men... p er en reference til selve objektets data, så du kan fra metoden:

string GetPersonsCprNumber(Person personInstance)
{
  ...
}

tilgå de samme data - som du kan tilgå fra koden her:
Person p = new Person();
GetPersonsCprNumber(p);

så hvis du i metoden gør sådan noget som dette her:
string GetPersonsCprNumber(Person personInstance)
{
  personInstance.Name = "hugo";
}

vil det altså resultere i, at du - der hvor du havde denne kode:
Person p = new Person();
GetPersonsCprNumber(p);

vil kunne se det metoden har gjort på objektet... altså - p.Name vil være "hugo"

Men men ... hvis du i metoden gør sådan her:
string GetPersonsCprNumber(Person personInstance)
{
  personInstance = null;
}

vil du blot ændre selve referencen (altså pegepinden til personobjektet), og da referencen er sendt til metoden som en kopi, vil du stadig kunne arbejde videre med dit personobjekt derfra hvor du har kaldt metoden.

...

der er altså ikke noget entydigt svar på hvad du skal gøre med de parametre du har til rådighed i metoden.... det er afhængig af parametertypen, og den opgave metoden skal løse.

desuden .... og det kan være at du lige skal vente et øjeblik med det, så kan du notere dine parametre med forskellige nøgleord - ref og out, men dem kan vi lige tage senere.

og det med dine eventhandlers... så vil jeg gerne anbefale at du holder eventhandlers så fri for logik som muligt.

mvh
Avatar billede c-sharp Nybegynder
24. marts 2006 - 06:17 #2
Hej Snepnet, det var ellers noget af et grundigt svar :-)

Jeg havde udtrykt mig forkert i det første spørgsmål, beklager. Jeg mente ikke globale variabler men klasse variabler. Hvordan bruger jeg dem i asp.net for de mister jo sin værdie for hvert postback?

Med hensyn til parameterne i metoden er det så ikke også muligt at modtage selve objectet, istedet for referencen?
Avatar billede snepnet Nybegynder
24. marts 2006 - 08:31 #3
ahh... det er lidt afhængig af hvad det er for variable... hvis du bare har brug for at gemme nogle simple typer kan du bruge viewstate, eller kontrolstate (det sidste kan ikke slås fra, men er en 2.0 ting)... de andre nævnte muligheder er også gangbare.

nej - for referencetyper får du en reference, men den giver dig jo mulighed for at arbejde direkte med objektet - såh... hvad savner du?

mvh
Avatar billede c-sharp Nybegynder
24. marts 2006 - 08:45 #4
Det var bare et spørgsmål, jeg mangler ikke noget endnu :-)

Med hensyn til de klasse variabler,  Jeg synes måske ikke umildbart at det er særlig overskuligt at gemme tingene i et viwestate da den ikke er erklæret et centralt sted direkte i klassen, men det er måske bare noget jeg skal vende mig til?
Avatar billede snepnet Nybegynder
24. marts 2006 - 08:58 #5
well... det er også meget almindeligt at lave properties der wrapper viewstate-variable... her f.eks. tekst-property'en på en button:

public string Text
{
      get
      {
            string text = (string) this.ViewState["Text"];
            if (text != null)
            {
                  return text;
            }
            return string.Empty;
      }
      set
      {
            this.ViewState["Text"] = value;
      }
}

så tilgår du værdierne pænt og nydeligt i resten af koden.

mvh
Avatar billede c-sharp Nybegynder
24. marts 2006 - 09:10 #6
Kunne jeg så med fordel lave min engne instanser af string, int osv. som jeg kunne bruge på den måde i mit framework:

eks.

private minString test_String;
private minint test_Inet

Forstår du hvad jeg mener?
Avatar billede snepnet Nybegynder
24. marts 2006 - 09:37 #7
jeg ville nok hellere gå efter en ViewStateVar<T>
mvh
Avatar billede c-sharp Nybegynder
24. marts 2006 - 09:41 #8
Hvad mener du med det?
Avatar billede snepnet Nybegynder
24. marts 2006 - 11:27 #9
jeg tænkte på noget i denne stil:

ViewStateVar<int> someInt = new ViewStateVar<int>(150);

og så i koden
someInt.Value++;

hvilket så kunne lade sig gøre for enhver type der kan serialiseres til viewstate
ViewStateVar<DateTime> someDate = new ViewStateVar<int>(DateTime.Now);
someDate.Value.AddHours(1);

det kunne jo være meget smart, men der er nogle problemer omkring det, så det var egentlig ikke noget rigtig godt forslag er jeg bange for.

... jeg kigger på det lidt senere, og giver dig en melding hvis jeg finder på noget.

mvh
Avatar billede c-sharp Nybegynder
11. april 2006 - 09:05 #10
Har du fundet på noget her?
Avatar billede snepnet Nybegynder
11. april 2006 - 16:30 #11
hehe - godt du mindede mig om det... havde svedt det ud igen.
mvh
Avatar billede snepnet Nybegynder
11. april 2006 - 22:01 #12
egentlig ikke rigtig ... du kan få en sessionvariable indtil videre ;o)
(det er bare for at vise princippet)

// aspx
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:Label ID="lblValue" runat="server"></asp:Label>
        <br />
        <asp:Button ID="btnPostBack" runat="server" OnClick="btnPostBack_Click" /> 
    </form>
</body>
</html>


// og koden:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
    private SessionVariable<int> m_SomeNumber = new SessionVariable<int>("name");

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            m_SomeNumber.Value = 100;
            ShowValue();
        }
    }
 
    protected void btnPostBack_Click(object sender, EventArgs e)
    {
        m_SomeNumber.Value++;
        ShowValue();
    }

    private void ShowValue()
    {
        lblValue.Text = m_SomeNumber.Value.ToString();
    }
}

public class SessionVariable<T>
{
    private string m_Name;
    private Page m_PageInstance;

    public T Value
    {
        get
        {
            SetPageInstance();
            return (T)m_PageInstance.Session[m_Name];
        }
        set
        {
            SetPageInstance();
            m_PageInstance.Session[m_Name] = value;
        }
    }
       
    public SessionVariable(string name)
    {
        m_Name = name;
    }

    private void SetPageInstance()
    {
        m_PageInstance = HttpContext.Current.Handler as Page;

        if (m_PageInstance == null)
            throw new ApplicationException("...");
    }
}

... ikke ligefrem produktionskode, men jeg håber det viser et eller andet.

mvh
Avatar billede c-sharp Nybegynder
03. maj 2006 - 17:37 #13
Jeg forstår bare ikke at man ikke på en pæne og nem måde kan erkære variabler i sin codebehind som holder deres værdie efter postback. Er det ikke en mangle?
Avatar billede snepnet Nybegynder
03. maj 2006 - 17:48 #14
jeg synes egentlig det er en rimelig pæn måde - altså at pakke en variabel ind med en property - der så mapper til viewstate, session ell.
det sidste eksempel var sådan lidt et forsøg på at automatisere det lidt (der er andre eksempler rundt omkring).
hvis hele tilstanden altid blev gemt - ville det f.eks. medføre nogle skaleringsissues.
mvh
Avatar billede c-sharp Nybegynder
03. maj 2006 - 17:51 #15
det jeg mente var om det ikke havde været smart at der i asp.net var nogle typer som kunne holde en værdie efter postback?

Smid bare et svar, jeg er glad for de eksempler du har lavet :-)
Avatar billede snepnet Nybegynder
03. maj 2006 - 18:37 #16
tjoh - det kunne det godt have været ... det er jo altid rart med muligheder ;o)
mvh
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