Vra

Ek het nie op die oomblik hierdie kwessie , maar jy weet nooit, en gedagte-eksperimente is altyd pret.

ignoreer die ooglopende probleme wat jy sal hê met jou argitektuur te hê om selfs probeer hierdie , kom ons aanvaar dat jy 'n paar verskriklik geskryf kode van iemand anders se ontwerp het, en wat jy nodig het om 'n doen n klomp van die wye en gevarieerde bedrywighede in dieselfde kode blok, bv:

WidgetMaker.SetAlignment(57);
contactForm["Title"] = txtTitle.Text;
Casserole.Season(true, false);
((RecordKeeper)Session["CasseroleTracker"]).Seasoned = true;

vermenigvuldig met 'n honderd. Sommige van hierdie kan werk, ander dalk erg verkeerd loop. Wat jy nodig het is die C # ekwivalent van "op fout CV volgende", anders gaan jy beland kopieer en plak probeer-vangste rondom die baie reëls van die kode.

Hoe sou jy probeer om hierdie probleem aan te pak?

Was dit nuttig?

Oplossing

Dit is redelik voor die hand liggend dat jy die kode in VB.NET, wat eintlik wel op Fout Hervat Volgende , en die uitvoer van dit in 'n DLL om C #. Enigiets anders is net 'n deurbringer  vir straf.

Ander wenke

public delegate void VoidDelegate();

public static class Utils
{
  public static void Try(VoidDelegate v) {
    try {
      v();
    }
    catch {}
  }
}

Utils.Try( () => WidgetMaker.SetAlignment(57) );
Utils.Try( () => contactForm["Title"] = txtTitle.Text );
Utils.Try( () => Casserole.Season(true, false) );
Utils.Try( () => ((RecordKeeper)Session["CasseroleTracker"]).Seasoned = true );

Refactor in individuele, goed genoem metodes:

AdjustFormWidgets();
SetContactTitle(txtTitle.Text);
SeasonCasserole();

Elk van dié behoorlik beskerm word.

Ek sou sê doen niks .

Yup dis reg, niks doen nie.

Jy het duidelik geïdentifiseer twee dinge vir my gesê:

  1. Jy weet die argitektuur is borked.
  2. Daar is 'n ton van hierdie kak.

Ek sê:

  • Doen niks.
  • Voeg 'n globale fout hanteerder om vir jou 'n e-pos stuur elke keer as dit gaan Boom.
  • Wag totdat iets val oor (of versuim 'n toets)
  • Die korrekte dat (refactoring as wat nodig is binne die bestek van die bladsy ).
  • Herhaal elke keer as 'n probleem opduik.

Jy sal hierdie opgeklaar in geen tyd as dit is so sleg nie. Ja ek weet dit sucky klink en jy kan trek jou hare uit met bugfixes om mee te begin, maar dit sal jou toelaat om regmaak die behoeftige / karretjie kode voor die (groot) hoeveelheid -kode wat kan eintlik werk nie saak hoe crappy dit lyk.

As jy begin om te wen die oorlog, sal jy 'n beter hanteer op die kode het (as gevolg van al jou refactoring) sal jy 'n beter idee vir 'n wen-ontwerp vir dit ..

Probeer om dit alles draai in borrelplastiek is waarskynlik gaan net 'n lang om te doen om te neem en jy sal nog nie enige nader aan die vaststelling van die probleme wees.

misluk Fast

Om uit te brei, ek dink ek bevraagteken die vraag. As 'n uitsondering is gegooi, hoekom sou jy wil hê dat jou kode om net voort te gaan asof niks gebeur het nie? Óf jy verwag uitsonderings in sekere situasies, in welke geval jy 'n drie-vangs blok skryf om daardie kode en hanteer hulle of daar is 'n onverwagte fout, in welke geval jy jou aansoek moet verkies om te staak, of probeer, of misluk. Nie voort te gaan soos 'n gewonde zombie gekerm 'brein'.

Dit is een van die dinge wat met 'n voorverwerker is nuttig vir. Jy kan 'n makro dat uitsonderings sluk definieer, dan met 'n vinnige script byvoeg dat makro aan al die lyne.

So, as dit was C ++, jy kan iets soos dit te doen:

#define ATTEMPT(x) try { x; } catch (...) { }
// ...
ATTEMPT(WidgetMaker.SetAlignment(57));
ATTEMPT(contactForm["Title"] = txtTitle.Text);
ATTEMPT(Casserole.Season(true, false));
ATTEMPT(((RecordKeeper)Session["CasseroleTracker"]).Seasoned = true);

Ongelukkig nie baie tale lyk na 'n voorverwerker soos C / C ++ sluit het.

Jy kan jou eie voorverwerker skep en voeg dit as 'n pre-bou stap. As jy voel soos heeltemal outomatisering dit kan jy waarskynlik skryf 'n voorverwerker dat die werklike kode lêer sal neem en voeg die drie / vangs dinge in sy eie (so jy hoef nie aan dié PROBEER (blokke om die kode met die hand by te voeg)) . Om seker te maak dit verander net die lyne dit veronderstel is om te kan moeilik maar wees (moet veranderlike verklarings, lus konstrukte, ens oor te slaan na dat jy nie die opbou breek).

Maar ek dink dit is verskriklik idees en moet nooit gedoen nie, maar die vraag is gevra. :)

Regtig, jy moet nooit dit te doen. Wat jy nodig het om uit te vind wat die oorsaak van die fout en dit reg te stel. Sluk / ignoreer foute is 'n slegte ding om te doen, so ek dink die korrekte beantwoord hier is "Fix die fout, nie ignoreer dit!". :)

On Error Resume Next is 'n baie slegte idee in die C # wêreld. Nie sou die toevoeging van die ekwivalent om werklik On Error Resume Next jou te help. Al wat dit sal doen is laat jy in 'n swak toestand waarin meer subtiele foute, data verlies en moontlik kan veroorsaak data korrupsie.

Maar om die vraag wat hom toekom gee, jy kan 'n globale hanteerder voeg en maak seker die TargetSite om te sien watter metode borked. Dan kan jy ten minste weet wat lyn dit borked op. Die volgende deel sou wees om te probeer en uit te vind hoe om die "volgende verklaring" op dieselfde manier die debugger doen dit stel. Hopelik jou stapel sal nie afrol op hierdie punt of jy kan herskep nie, maar dit is beslis 'n skoot moeite werd. Maar, gegewe hierdie benadering die kode sal moet hardloop in Debug af elke keer, sodat jy wil hê jou debug simbole ingesluit.

As iemand genoem, VB kan hierdie. Hoe gaan dit doen dit op dieselfde manier in C #? Tik betroubare reflector:

Dit:

Sub Main()
    On Error Resume Next

    Dim i As Integer = 0

    Dim y As Integer = CInt(5 / i)


End Sub

vertaal in hierdie:

public static void Main()
{
    // This item is obfuscated and can not be translated.
    int VB$ResumeTarget;
    try
    {
        int VB$CurrentStatement;
    Label_0001:
        ProjectData.ClearProjectError();
        int VB$ActiveHandler = -2;
    Label_0009:
        VB$CurrentStatement = 2;
        int i = 0;
    Label_000E:
        VB$CurrentStatement = 3;
        int y = (int) Math.Round((double) (5.0 / ((double) i)));
        goto Label_008F;
    Label_0029:
        VB$ResumeTarget = 0;
        switch ((VB$ResumeTarget + 1))
        {
            case 1:
                goto Label_0001;

            case 2:
                goto Label_0009;

            case 3:
                goto Label_000E;

            case 4:
                goto Label_008F;

            default:
                goto Label_0084;
        }
    Label_0049:
        VB$ResumeTarget = VB$CurrentStatement;
        switch (((VB$ActiveHandler > -2) ? VB$ActiveHandler : 1))
        {
            case 0:
                goto Label_0084;

            case 1:
                goto Label_0029;
        }
    }
    catch (object obj1) when (?)
    {
        ProjectData.SetProjectError((Exception) obj1);
        goto Label_0049;
    }
Label_0084:
    throw ProjectData.CreateProjectError(-2146828237);
Label_008F:
    if (VB$ResumeTarget != 0)
    {
        ProjectData.ClearProjectError();
    }
}

Skryf die kode. Probeer om stelle state wat logies is afhanklik van mekaar te vind, sodat as 'n mens nie dan die volgende mense maak nie sin nie, en te stoot hulle af in hul eie funksies en sit probeer-vangste ronde hulle, as jy wil hê dat die gevolg van ignoreer wat en voortgaan.

Dit kan jou help om in identifing die stukke dat die meeste probleme het.

@ JB King Dankie vir die herinner my. Die Logging aansoek blok het 'n Instrumentasie Event wat gebruik kan word om gebeure op te spoor, kan jy meer inligting oor die MS Enterprise biblioteek dokumente vind.

Using (New InstEvent)
<series of statements> 
End Using

Al die stappe in hierdie behulp sal teruggevoer word na 'n log-lêer, en jy kan ontleed wat uitgegaan om te sien waar die log breek (ex gegooi) en id die hoë oortreders.

As gevolg hiervan is regtig jou beste bet, maar as jy 'n baie, kan dit help jy leer ken, die ergste oortreders.

Jy kan gebruik goto, maar dit is nog steeds deurmekaar.

Ek het eintlik wou 'n soort van 'n enkele verklaring probeer-vangs vir 'n rukkie. Dit sou nuttig in sekere gevalle, soos die toevoeging van meld code of iets wat jy nie wil hê om die hoofprogram vloei onderbreek as dit nie werk nie.

Ek vermoed iets gedoen kan word met 'n paar van die eienskappe wat verband hou met linQ, maar het nie regtig tyd om op die oomblik kyk na dit. As jy 'n manier om 'n verklaring te draai as 'n anonieme funksie, dan gebruik 'n ander een te noem dat binne 'n drie-vangs blok dit sal werk net kon kry ... maar nie seker of dit is moontlik net nog nie.

As jy die samesteller kan kry om vir jou 'n uitdrukking boom gee vir hierdie kode, dan kan jy dit uitdrukking boom verander deur elke stelling te vervang met 'n nuwe drie-vangs blok dat die oorspronklike verklaring vou. Dit is nie so vergesog as wat dit klink; vir LINQ, C # verkry die vermoë om lambda uitdrukkings te vang as uitdrukking bome wat gemanipuleer kan word in die gebruiker-kode tydens looptyd.

Hierdie benadering is nie moontlik vandag met NET 3.5 - as vir geen ander rede as die gebrek aan 'n "probeer" verklaring in System.Linq.Expressions. Dit kan egter baie goed lewensvatbaar wees in 'n toekomstige weergawe van C # sodra die merge van die DLR en LINQ bome uitdrukking is voltooi.

Hoekom nie die besinning in c # gebruik? Jy kan 'n klas wat besin oor die kode en gebruik line # sek as die wenk vir wat in elke individu probeer / vangs blok te sit skep. Dit het 'n paar voordele:

  1. Die effens minder lelik as dit nie regtig wat jy nodig het mangelen jou bronkode en jy kan dit net gebruik tydens debug modes.
  2. Jy leer iets interessant oor c # terwyl die uitvoering daarvan.

Ek egter sou aanbeveel teen enige van hierdie, tensy jy die oorname van instandhouding van someelses werk en wat jy nodig het om 'n handvatsel te kry op die uitsonderings, sodat jy hulle kan regmaak. Kan pret om al te skryf.

vraag Fun; uitermate vreeslik.

Dit sal lekker wees as jy 'n makro kan gebruik. Maar dit is blaas C #, sodat jy dit kan oplos met 'n paar voorverwerker werk of 'n eksterne hulpmiddel om jou lyne in individuele drie-vangs blokke te draai. Nie seker of jy bedoel jy wou nie die hand draai dit of dat jy wou probeer-vangs te vermy heeltemal .

geknoei rondom met hierdie, Ek het probeer etiketteer elke lyn en spring terug van 'n enkele vangs, sonder veel sukses. Maar Christopher ontbloot die korrekte manier om dit te doen. Daar is 'n paar interessante bykomende bespreking van hierdie by Dot Net Gedagtes en by NET Blog Mike stalletjie se .

EDIT: Natuurlik. Die try-catch / switch-goto oplossing gelys sal nie eintlik saam te stel aangesien die try etikette is out-of-omvang in catch. Iemand weet wat ontbreek om iets saam te stel?

Jy kan dit outomatiseer met 'n samesteller vir wysig stap of dalk hack up Mike stalletjie se inline IL instrument om 'n paar foute onkunde spuit.

( Orion Adrian se beantwoord oor die behandeling van die uitsondering en probeer om 'die volgende opdrag te interessant.)

Alles in ag genome, lyk dit soos 'n interessante en leersame oefening. Natuurlik, sal jy moet besluit op watter punt die poging om na te boots op 'n fout CURRICULUM VOLGENDE swaarder weeg as die poging om die kode te los. : -)

Vang die foute in die UnhandledException Event van die aansoek. Op dié manier, verwerkte execptions kan selfs aangeteken as die sender en enige ander inligting wat die ontwikkelaar sal redelike.

Ongelukkig is jy waarskynlik uit van geluk. Op Fout Hervat Volgende is 'n nalatenskap opsie wat oor die algemeen swaar word ontmoedig, en nie 'n gelykstaande aan my kennis in C # hê.

Ek sou aanbeveel verlaat van die kode in VB (Dit klink soos dit was die bron, gegewe jou spesifieke versoek om OnError ResumeNext) en skakeling met of van 'n C # dll of exe dat implemente watter nuwe kode wat jy nodig het. preform dan refactoring te veroorsaak dat die kode om veilig te wees, en te omskep hierdie veilige kode vir C # as jy dit doen.

Jy kan kyk na die integrasie van die Enterprise Biblioteek se hantering van uitsonderings komponent vir 'n idee van hoe om te hanteer verwerkte uitsonderings.

As dit vir ASP.Net aansoeke, daar is 'n funksie in die Global.asax genoem, "Application_Error" wat kry genoem in die meeste gevalle met katastrofiese mislukking om die ander geval gewoonlik.

Ignoreer al die redes wat jy wil hê om te verhoed dat dit te doen .......

As dit was bloot 'n behoefte om te hou # lyne, kan jy iets soos probeer:

int totalMethodCount = xxx;
for(int counter = 0; counter < totalMethodCount; counter++) {
    try {
        if (counter == 0) WidgetMaker.SetAlignment(57);
        if (counter == 1) contactForm["Title"] = txtTitle.Text;
        if (counter == 2) Casserole.Season(true, false);
        if (counter == 3) ((RecordKeeper)Session["CasseroleTracker"]).Seasoned = true;
    } catch (Exception ex) {
        // log here
    }
}

Maar wil jy hê om 'n ogie te hou oor veranderlike omvang hou as jy probeer om enige van die resultate van die oproepe hergebruik.

Hilite elke lyn, een op 'n tyd, 'omring met' probeer / vangs. Wat vermy die kopiëring plak jy genoem

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top