» »

c# kam lambda delegat shrani spremenljivke? (in njegov scope)

c# kam lambda delegat shrani spremenljivke? (in njegov scope)

Vapo1 ::

static class StaticniRazred
	{
		public static MethodInvoker FunkcijaGetDelegate(int NUM)
		{
			return () => { MessageBox.Show("NUM je: " + NUM.ToString()) };
		}
	}
//MethodInvoker je standardni parameterless void delegat


ko to poklicem:
Main()
{
MethodInvoker MI1 = StaticniRazred.FunkcijaGetDelegate(128);
MethodInvoker MI2 = StaticniRazred.FunkcijaGetDelegate(256);

			MI1.Invoke();
			MI2.Invoke();
}


vse gre kot pricakovano - pojavita se dva messageBoxa eden javi ""NUM je: 128" drugi pa "NUM je: 256"




////////

ok zdaj pa vprasanje....
kam se shrani integer NUM ??

delegati so kolkor vem "pointerji do funkcij" ... in nekako sem si vedno predstavljal, da je funkcija "recept", ki je zapisan samo enkrat na samo enem mestu nekje v ramu.... in da delegati potem vedno pointajo do te ene funkcije in ji vsakic pac podajo parametre ki jih potrebuje.....
tukaj je pa trik da sem uporabil lambda delega katerega koda je napisana znotraj "FunkcijaGetDelegate" funkcije - in ima kar magicno scope do zacasne lokalne spremenljivke NUM

torej ta spremenljivka NUM se mora nekam shraniti, da se lahko potem delegata kadarkoli in kjerkoli kasneje invokea in pokaze msgbox pravo steviljko


torej - a sem si narobe predstavljal, da so vse funkcije samo enkrat na enem mestu - kot nek "recept" ?? mogoce se te funkicje kopirajo za vsakega delegata.... mogoce vsak instance classa ima notri svoje kopije vseh svojih funkcij ki niso staticne ??


hvala

Vapo1 ::

se to...

mogoce je ta predstava kaj blizje:

predstavljal sem si da je funkcija ("recept") samo enkrat zapisan nekje na enem mestu v ramu... in potem ko se hoce executeat ta funkcija ("recept") se na stack skopira parametre in neko "procesorsko kodo" od te funkcije da se to izvede....
kaj pa delegati? mogoce isto zadevo skpirajo nekam v ram namesto na stack... in potem ko se jih invokea se to iz rama skopira na stack in CPU izvede ..... in poleg parametrov in "procesorske kode od te funkcije" delegati shranijo se kaksne dodatne unikatne lokalne spremenljivke(kot naprimer tale nas integer NUM), ki jih utegnejo potrebovati pri izvebi

darkolord ::

delegati so kolkor vem "pointerji do funkcij"
Ja, uporabljajo se že kot "function pointerji", v resnici pa niso ravno to - dejansko je delegat class. Zaradi tega lahko tudi deklariraš spremenljivke z delegatom kot tipom, ga podajaš kot parameter in ga instanciraš (če bi bil samo pointer do funkcije, tega ne bi glih mogel, ane)

Priporočam tole in tole za branje za začetek.

Zgodovina sprememb…

fiction ::

A ne bi deloval samo M1()?

Ce bi naredil malce drugace, tako da bi lahko podal num od zunaj v casu klica, bi se temu reklo "closure" (zaprtje). Tukaj pise malo vec o tem kako je vse skupaj implementirano. Naceloma moras shraniti kazalec na funkcijo in argumente iz casa ustvarjanja. Proste spremenljivke lahko "zapolnis" tudi kasneje ob klicu.

V tvojem primeru ni tako, saj ne mores metodi podati ob klicu argumentov niti tam notri ne uporabljas spremenljivk iz "scopa okrog" tistega, kjer se vse skupaj ustvari. Pomoje je zato tako, da dobis 2 anonimni metodi, pri cemer ena vraca "NUM je: 128" druga pa "NUM je: 256". Poleg tega imas se dva delegata, v M1 je npr. (kakorkoli ze, najbrz je v tistem objektu nekje naslov funkcije) shranjeno, da se mora poklicati prva funkcija.

Vprasanje je samo kdaj se ti dve anonimni metodi ustvarita - JIT ali v casu prevajanja? Mislim, da slednje, ker je najbrz prevajalnik dovolj pameten, da pogrunta, da je pogoj, da prides do tocke, ko potrebujes metodo, vedno izpolnjen.

Zgodovina sprememb…

  • spremenil: fiction ()

fiction ::

darkolord je izjavil:

delegati so kolkor vem "pointerji do funkcij"
Ja, uporabljajo se že kot "function pointerji", v resnici pa niso ravno to - dejansko je delegat class. Zaradi tega lahko tudi deklariraš spremenljivke z delegatom kot tipom, ga podajaš kot parameter in ga instanciraš (če bi bil samo pointer do funkcije, tega ne bi glih mogel, ane)
Se strinjam s povedanim. Delegat je poenostavljeno povedano razred, ki ima nekje v sebi napisan kazalec na funkcijo. Ampak fora ni toliko v tem, da bi z delegatom lahko pocel kaj vec kot pa s "function pointerjem", ampak kvecjemu manj in je na ta nacin jezik bolj "type-safe". Kam "kaze" delegat lahko le zelo kontrolirano spreminjas, medtem ko pointer lahko nastavis, da kaze kamorkoli v pomnilnik, npr. tudi na funkcijo z drugim "podpisom" ali pa se huje na cisto nekaj tretjega.

Zgodovina sprememb…

  • spremenil: fiction ()

darkolord ::

Ampak fora ni toliko v tem, da bi z delegatom lahko pocel kaj vec kot pa s "function pointerjem"
Seveda, tisto so samo posledice tega, da je zadaj class

KaRkY ::

Lambde niso kazalci na funkcije ampak koda ki se runtime evaluira. Zato pa lahko podaš neke pogoje v funkcijo in kasneje pogledaš kakšni so(LINQ). Vrednosti spremenljivk pa so shranjene normalno le referenco ima ta expression. Če se motim me popravite ampak vem da sem že nekaj poskušal evaluirati lambde.
When you look long into an abyss, the abyss looks into you

fiction ::

KaRkY je izjavil:

Lambde niso kazalci na funkcije ampak koda ki se runtime evaluira.

A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types. (vir)
Lambda racun je cisto matematicen koncept (z enako "izrazno mocjo" kot Turingov stroj). Pri funkcijskem programiranju se uporabja lambda izraz v stilu x preslikaj v x + 1. Nimas pa cisto nobenih drugih spremenljivk v katerih bi si lahko hranil stanje ali pa zank. Tako da je funkcija res taka kot v matematiki in nima nobenih stranskih ucinkov. Pomoje "(x) => expression" steje kot "pravi" lambda izraz, "() => { statement }" pa ne ravno, posebej ce imajo ukazi le stranski ucinek, da nekaj izpisejo.

V .NET je lambda izraz IMHO le neke vrste syntactic sugar. Kul je to, da se samodejno sklepa o podatkovnih tipih, ter da je zapis bolj kompakten. Ampak to je pa to. Se vedno mora obstajati neka anonimna metoda, ki vsebuje tisti statement. In bytecode za to se najbrz zgenerira ze ob prevajanju. JIT je verjetno le prevajanje te vmesne kode v pravo strojno kodo. Mocno dvomim o tem, da bi se lahko kar neka nova metoda v runtimu "dostukala". V tem primeru v bistvu lambda izraz lahko priredis delegatu.

Drugi nacin pa lahko uporabis v "(x) => expression" primeru. Takrat to lahko priredis drevesu izrazov (ExpressionTree). To potem kolikor stekam pomeni, da je v programu en podatek vec, ni pa posebne anonimne metode. In v runtimu imas nacin, da se evaluira vrednost izraza, ki je zapisan s pomocjo tega (ali pa kateregakoli) drevesa.

noraguta ::

fiction je izjavil:

KaRkY je izjavil:

Lambde niso kazalci na funkcije ampak koda ki se runtime evaluira.

A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types. (vir)
Lambda racun je cisto matematicen koncept (z enako "izrazno mocjo" kot Turingov stroj). Pri funkcijskem programiranju se uporabja lambda izraz v stilu x preslikaj v x + 1. Nimas pa cisto nobenih drugih spremenljivk v katerih bi si lahko hranil stanje ali pa zank. Tako da je funkcija res taka kot v matematiki in nima nobenih stranskih ucinkov. Pomoje "(x) => expression" steje kot "pravi" lambda izraz, "() => { statement }" pa ne ravno, posebej ce imajo ukazi le stranski ucinek, da nekaj izpisejo.

V .NET je lambda izraz IMHO le neke vrste syntactic sugar. Kul je to, da se samodejno sklepa o podatkovnih tipih, ter da je zapis bolj kompakten. Ampak to je pa to. Se vedno mora obstajati neka anonimna metoda, ki vsebuje tisti statement. In bytecode za to se najbrz zgenerira ze ob prevajanju. JIT je verjetno le prevajanje te vmesne kode v pravo strojno kodo. Mocno dvomim o tem, da bi se lahko kar neka nova metoda v runtimu "dostukala". V tem primeru v bistvu lambda izraz lahko priredis delegatu.

Drugi nacin pa lahko uporabis v "(x) => expression" primeru. Takrat to lahko priredis drevesu izrazov (ExpressionTree). To potem kolikor stekam pomeni, da je v programu en podatek vec, ni pa posebne anonimne metode. In v runtimu imas nacin, da se evaluira vrednost izraza, ki je zapisan s pomocjo tega (ali pa kateregakoli) drevesa.


praktično je lambda expression tree. gre za tenstanje kode precej podobno templatom v c++. se pa koda dejansko lahko emita v runtimu prek S.R.E.. btv v nekaterih funkcijskih pristopih je
Pri funkcijskem programiranju se uporabja lambda izraz v stilu x preslikaj v x + 1.

nedopusten izraz (mutabli so zločesti).
Pust' ot pobyedy k pobyedye vyedyot!

Sportmania ::

Če si lahko na hitrco sposodim temo.

Kako dostopam do spremenljivke v gumbu 1 iz gumba 2.

Npr on click button 1 dogodek nardim spremenljivko x katero hočem uporabat v dogodku gumba 2 pa mi nikakor ne rata do nje?


darkolord ::

Ne moreš. Naredi jo drugje (npr. znotraj classa, v katerem sta ta dva gumba).

Zgodovina sprememb…

Sportmania ::

Ne morem, ker hočem, da ko kliknem gumb 1 se začne šteti čas ko pa gumb 2 se pa ustavi in se odšteje, da vidim pretečen čas (štoparica).
Zdej, če sem pravilno dojel se zato uporablja TIMER? Samo timer.start(); timer.stop(); kako pa pol to kej izračunam pretečen čas?


Zgodovina sprememb…

kogledom ::

darkolord ti je dal pravilno rešitev.
Znotraj razreda, kjer imaš gumba, ustvari spremenljivko start tipa DateTime. Ob kliku na gumb nastavi start na DateTime.Now. Ob kliku na drugi gumb pa izračunaj TimeSpan z DateTime.Now - start.

Zgodovina sprememb…

  • spremenil: kogledom ()

Sportmania ::

Hvala! Sedaj dela me pa še vedno zanima kako bi naredil, da ko pritisnem STOP, da se ura ustavi sedaj se mi samo izpiše pa hočem da se štoparica povsem zaustavi.

    public partial class Form1 : Form
    {
        DateTime start = DateTime.Now;
        public Form1()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            TimeSpan razlika = DateTime.Now - start;
            textBox1.Text = Convert.ToString(razlika);
        }
    }


Zgodovina sprememb…

darkolord ::

Kakšna štoparica? :)

Sportmania ::

Klasična. Ko pritisnem gumb 1 se mi začne šteti čas, ko pritisnem gumb 2 se pretečeni čas izpiše v textboxu ampak še vedno pa teče naprej želim pa, da se povsem neha šteti. Sicer delam na programu, ki bi ga povezal z neko drugo aplikacijo v autorun in, ko bi se le-ta zagnala bi zraven vedno bil še ta program in štel čas koliko je aplikacija prižgana.


darkolord ::

V tvojem primeru se čas nič ne "šteje", torej ne moreš kar "nehat štet". Zabeleži se sistemski čas na začetku, ta pa se na koncu odšteje od trenutnega sistemskega časa.

Tako kot če pogledaš ročno uro, čez nekaj minut pa spet in ta dva časa odšteješ. Kako to ustaviš? :)

Sportmania ::

Aha no potem pa kak drug način štopanja, če obstaja sicer pa to nima veze zanima me kako bi to povezal z neko aplikacijo mislil sem, da bi dodal moj .exe program v autorun aplikacije pa, da bi se zagnal takrat kot aplikacija samo kje bi potem naštimal kdaj se ugasne? (TAKRAT KO APLIKACIJA BI SE MOGEL)


commissar ::

uhka tko nrdš, de ku unga proghrama ni vč umes med fsemi procesi pol nehaš štopat, ku pa se pujafi pa zakurblaš uhro.

Sportmania ::

Aha hvala kaj za procese rabim using System.Diagnostics; me pa zanima katera metoda ugotovi, če je proces prižgan oziroma ugasnjen našel sem samo process.start(); in metodo process.starttime

Mogoče samo še to, če kdo ve kako bi naredu štoparico, da bi v textboxu kazala čas v intervalu sekunde. Drugače pa me primarno zanima prvo vprašanje.

Process[] pname = Process.GetProcessesByName("notepad");
if (pname.Length == 0)
MessageBox.Show("nothing");
else
MessageBox.Show("run");


Sem našu zdej tole kodo zakaj more bit tabela?

HVALA


Zgodovina sprememb…

darkolord ::

Ker je lahko več procesov z istim imenom.

Sportmania ::

Ne v principu se mi gre za program, ki bi štel kolko časa je prižgan nek proces: igra. Pa sem zdej dodal naslov igre.exe tam kjer piše notepad pa sploh ne dojame kaj to samo te vgrajene procese zazna?

Za nič drugega mi ne zazna samo notepad?


Zgodovina sprememb…

Sportmania ::

Sej dela zdej zazna samo nevem še vedno kak bi naredo?




Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

C# threadanje in gui

Oddelek: Programiranje
8771 (662) darkolord
»

[c#] Risanje z miško

Oddelek: Programiranje
221425 (1106) japol
»

[c#] Vprasanje glede BackGroundWorker classa in spreminanja gui elementa

Oddelek: Programiranje
6784 (710) Ericssony
»

Kateri programski jezik?

Oddelek: Programiranje
494540 (3153) kopernik
»

[c++] standardni c++ in dogodki(events)

Oddelek: Programiranje
121749 (1574) yeti

Več podobnih tem