webForumDet fria alternativet

Sökkriterie-objekt?

.NET

16 svar · 660 visningar · startad av Lukaspojken

Medlem sedan maj 20011 312 inlägg
Frågan#1

Det är så att jag har en sida med ett sökformulär som växt från litet till stort. Jag tycker inte det är hållbart att skicka ner massa inparametrar till metoder. Risken för fel ökar väldigt mycket.

Det jag vill göra är att i GUI:t fylla ett sökkriterie-objekt och skicka ner det. Det jag undrar lite över hur ni skulle skapat ett sådant objekt. Skulle ni bara kört med publika fält för det är väl lite överdesign att skapa properties? Skulle man kanske istället välja en struct istället för en klass?

Så en sista fråga :) Vad ska man ge för namn på ett sådant här objekt?

Medlem sedan aug. 20003 575 inlägg
#2

XXXXCriteria :)

Medlem sedan maj 20011 312 inlägg
#3

Jag är lite osäker på singular i namnet :) För objektet är lite av en behållare av sökkriterier men ändå inte en kollektion.

Andra varianter jag tänkt är
xxxSearchCriterias
xxxSearchCriteriaContainer

Men skulle du gjort det till en struct eller class? Publika fält bara?

Medlem sedan aug. 20003 575 inlägg
#4

Criterion blir det isåfall.

Medlem sedan maj 20011 312 inlägg
#5

Där ser man...då har jag lärt mig något nytt. Jag frågade också en engelskman och han lärde sig även något nytt :) Men jag tror xxxSearchCriteriaContainer är det som det lutar åt...

Medlem sedan mars 20007 896 inlägg
#6

Skulle ni bara kört med publika fält för det är väl lite överdesign att skapa properties?

Det behöver inte vara överdesign, om du bygger in kontroller av indata i dina proppar. Får namn vara kortare än 3 tecken? Kan telefonnummer innehålla andra tecken än siffror och +? Ska indata formateras på något sätt? osv. Då kanske du vill kasta Exceptions uppåt i hierarkin eller ta hand om "felen" på en gång. Publika fält brukar man vilja undvika, och istället satsa på inkapsling - eftersom att man om inte annat vid ett senare tillfälle kan bygga in viss logik i klassen utan att behöva ändra i andra klasser och metoder.

Medlem sedan maj 20011 312 inlägg
#7

Att anropa en property eller ett publikt fält skiljer sig inte åt kodmässigt. Så just i detta fallet med ett sådant objekt skulle jag nog förespråka användning av publika fält. Detta för att det blir mindre kod (komplexiteten minskar). Skulle man dock vilja ändra i framtiden så koden går mot en property istället för ett fält då måste man kompilera om för att det ska fungera, dvs det går inte att tex bara kompilera om domän-dll:n och tro att GUI-dll:n fungerar utan kompilering. Men i princip alltid kompilerar man om allt och gör en publicering.

Eller finns det någon annan fördel att använda properties framför fält i just detta fallet?

Jag tycker dock att det är intressant att du tar upp detta med validering. För det har jag inte tänkt på. I och för sig är det inte aktuellt just nu eftersom det är fritextfält rakt igenom. Men det är en bra poäng! För jag kan tänka mig att liknande problem i andra sammanhang, dvs när andra sökformulär i andra projekt blir komplexa (därför är jag bland annat lite intresserad av namnstandard).

Medlem sedan mars 20007 896 inlägg
#8

Lukaspojken skrev:

Att anropa en property eller ett publikt fält skiljer sig inte åt kodmässigt. Så just i detta fallet med ett sådant objekt skulle jag nog förespråka användning av publika fält. Detta för att det blir mindre kod (komplexiteten minskar).

Hmm, skiljer sig inte åt kodmässigt? Du menar att du inte går efter några namnkonventioner - eller att ni på ert företag har egna konventioner? ;)

Instansvariabler bör börja med liten bokstav, oavsett vilken access det är på dom. Proppar däremot bör börja med stor bokstav. Visst kan man "lura" användarna av klassen genom att låta en proppe egentligen vara ett publikt fält - men det är ingenting jag skulle rekommendera. I så fall är det bättre att bygga in proppar från början - men utelämna logik. Komplexiteten skulle vara oförändrad (utan logik) och det blir inte mycket mer kod.

class SearchCriterion {
   public string name = "";

   public string Name { set; get; }
}
Medlem sedan maj 20011 312 inlägg
#9

Jag kör med namnstandarder men detta är lite av ett specialfall. Är förresten inte namnstandarden _name. Annars får du nog lätt krockar med inparameterar till tex konstruktorn. Typ

public DinKonstruktor(int id)
{
     _id = id;

Eller vad skulle du kalla inparametern om du kallar fälter för "id"?

En sak till, tyvärr kan jag inte köra med "public string Name { set; get; }" annars skulle det varit ett klart alternativ framför publika fält. Jag kör ramverk 2.0 och VS 2005 men snart så blir det uppgradering :)

Så jag måste skriva alltså skriva enligt detta:

private string _name = "";
public int Name
{
get { return _name; }
set { _name = value; }
}

Det blir rätt mycket extra kod om man har 20 kriterier. Men jag byter dock åsikt till att om man kör en högre framework än 2.0 så bör man välja properties av den enklavarianten, dvs "public string Name { set; get; }" istället för publika fält.

Medlem sedan mars 20007 896 inlägg
#10

Understreck bör användas enbart vid privata variabler, inte vid publika. Och man får inga krockar med inparametrar om man använder självreferensen 'this' - vilket jag brukar förespråka att man gör.

Jag skulle nog ha använt proppar trots att du sitter med 2.0. Man förebygger framtida problem genom inkapsling, och den lilla extra kod som behövs tycker jag inte påverkar komplexiteten alls.

Medlem sedan maj 20011 312 inlägg
#11

Ok, jag trodde du menade att du inte körde _-tecknet för privata variabler.

Varför förespråkar du förresten användadet av this? Kör du this på allt inne i klassen eller bara vissa delar som kan krocka? Jag minns att jag läste någon artikel om detta för länge sedan och där förespråka man att inte använda det (och efter det sluta jag med det). Jag minns inte vad argumenten var men jag tror dels på grund av minimal prestandaförbättring samt av några andra anledningar. Någon annan kanske vet? Men varför vill du att man ska använda this?

Medlem sedan maj 20011 312 inlägg
#12

Jag fick ett svar från en kompis om detta med this och inte this. Enligt ReSharper så anser detta verktyg att this är redundant. Det förklarar dock inte varför man inte ska använda det. Visst, jag kan hålla med om att onödig kod inte ska skapas. Men om du har en bra anledning för this så shoot :)

Medlem sedan mars 20007 896 inlägg
#13

Jag använder det för att jag tycker att det blir tydligare vilken variabel/referens som menas - då det uteslutande handlar om instansvariabler. Inga metod- eller block-variabler kan refereras till m.h.a. this. Ett understreck garanterar inte att det är en instansvariabel. Även om MS namnkonventioner menar att det ska handla om en instansvariabel/-referens så finns det ingenting som hindrar en från att skapa block-variabler som har inledande understreck.

Medlem sedan maj 20011 312 inlägg
#14

Varför tror du ReSharper ser this som redundant? Jag tror respharper också reagerar på att om du inte använder dig av _-tecknet för privata variabler. Så det borde lösa problemet du tar upp.

Medlem sedan aug. 20003 575 inlägg
#15

Lukaspojken skrev:

Varför tror du ReSharper ser this som redundant? Jag tror respharper också reagerar på att om du inte använder dig av _-tecknet för privata variabler. Så det borde lösa problemet du tar upp.

Man skall ju inte stirra sig blind på vad Resharper säger åt dig att göra även om det mesta är bra.

t.ex. verktyget NDepend som är ett ypperligt program i många delar varnar dig när du inte har m_XXX på dina medlemsvariabler, och det vill vi ju verkligen inte ha :P.

Du kan med hjälp av reflection bygga upp ett ganska trevligt objekt som blir ganska dynamiskt.

dvs.

public class Criterion
{
    public void AddCriteria(string propertyPath, IComparable value, RelationalOperator operator)
    {
        .......
    }
}

Annars kanske det räcker med en vanlig IList med namn och värde istället för en lång parameterlista.

Medlem sedan maj 20011 312 inlägg
#16

NDepend har jag inte någon erfarenhet av men ReSharper har väl ett ganska bra rykte bakom sig. Och det som ReSharpers "validering" bygger på något icke-genomtänkt.

Jag tror det lutar åt properties istället för lista. Det känns mer som ett lättare objekt att förstå, förvalta, validera m.m.

Medlem sedan mars 20007 896 inlägg
#17

Lukaspojken skrev:

Varför tror du ReSharper ser this som redundant? Jag tror respharper också reagerar på att om du inte använder dig av _-tecknet för privata variabler. Så det borde lösa problemet du tar upp.

För att det till viss del är det. 'this' måste ju användas i vissa fall, som vid överskuggning av variabler, för att skicka en referens till sig själv som parameter till någon metod, osv.

class MyClass {
   private int volume;
...
   public MyClass GenerateFromVolume(int volume) {
      if(this.volume > volume)
         return this;
      else
         return new MyClass(volume);
   }
...
}

I den ovanstående (inte så logiska) kodsnutten är man tvungen till att använda referensen this. I if-jämförelsen för överskuggningen och i raden under för att returnera referensen till sig själv. Det finns ingen annan väg att gå (förutom att döpa om parametern möjligtvis).

class Quadrant {
   private int baseline;
   private int height;
...
   public Quadrant CreateQuadrantFromHeight(int height) {
      return new Quadrant(this.baseline, height);
   }
...
}

I den här koden är this redundant. Den är helt onödig, eftersom att det inte finns någon annan variabel med namnet 'baseline'. Dock så, enligt mig, ökar den förståelsen för koden - jag förstår direkt (och hoppas att andra gör det också) att det är baslinjen för instansen som ska användas. Det går inte att ta miste på.

ReSharper hade antagligen gillat den övre koden bättre än den undre, där den hade plockat bort referensen till this. Men bara för att ReSharper gör det, tycker jag inte att man ska ta det som att man inte ska använda this. Microsoft Base Class Usage Guidelines hävdar till exempel att man bör använda this för de flesta (alla?) instansvariabler/-referenser. Microsoft StyleCop råder en också att använda this. Så varför lyssna på vad ReSharper säger, när andra verktyg säger motsatsen? :)

Alla programmerare har sin egen stil - gillar du understreck och alla i ditt företag är överens om er namnstandard, kör på det!

Jag ger ytterligare ett kodexempel att grunna på:

class MyClass {
...
   public void DoSomething() {
      /* Gör något roligt här */
      this.DoSomethingElse();
   }
...
}

Jämför mot:

class MyClass {
...
   public void DoSomething() {
      /* Gör något roligt här */
      DoSomethingElse();
   }
...
}

I det övre exemplet här är this verkligen redundant. Om man utelämnade this och gör direkt som i andra exemplet, så förstår man ändå direkt att det är en metod i den lokala instansen - det finns ingen annan möjlighet. Det kan ju inte vara en metod på ett annat objekt. Här förespråkar jag metod 2, alltså att man utelämnar själv-referensen.

(För övrigt säger också Microsoft User Guidelines att man inte ska deklarera instansfält som publika - utan att man ska gå via proppar ;))

258 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
120 ms — deklarationer (db)
0 ms — hämta statistik (cache)
133 ms — hämta tråd, inlägg och bilagor (db)
122 ms — ändringar (db)