Avatar billede CodingJoe Nybegynder
05. oktober 2012 - 19:53 Der er 25 kommentarer og
1 løsning

Efterspørger et pattern til at løse metoder med samme signatur+navn men forskellig returtype

Jeg har en metode, der giver mig fx en Liste af Biler (List<Bil>)

Lad os kalde den:

public Bil HentBil(int id){}

og en metode der giver os et XmlDocument istedet for Bil:

public XmlDocument HentBil(int id){}


Jeg legede lidt med tanken om at lave en generic metode, med constraints på XmlDocument og Bil:
Lidt a la

public T HentBil<T>(int id) where T : Bil, XmlDocument

...men det kan man slet ikke...jeg tænkte på et factory pattern af en eller anden art, men har svært ved at se hvordan...

Jeg giver sprøde points...da jeg selv gerne vil lære nogle af disse patterns.
Avatar billede CodingJoe Nybegynder
05. oktober 2012 - 19:56 #1
Den øverste linje i mit forrige indlæg skal erstattes med:
"Jeg har en metode, der giver mig fx et bil objekt"
Avatar billede arne_v Ekspert
05. oktober 2012 - 20:06 #2
public Bil HentBilAsBil(int id){}
public XmlDocument HentBilAsXmlDocument(int id){}

er nok den mest brugte loesning.
Avatar billede janus_007 Nybegynder
05. oktober 2012 - 20:11 #3
Du kan gøre sådan her.

public T HentBil<T>(int id) where T : XmlDocument

public T HentBil<T>(int id) where T : Bil
Avatar billede arne_v Ekspert
05. oktober 2012 - 20:13 #4
public T HentBil<T>(int id)
{
    if(typeof(T) == typeof(Bil))
    {
    }
    else if(typeof(T) == typeof(XmLDocument))
    {
    }
}

er grim
Avatar billede arne_v Ekspert
05. oktober 2012 - 20:17 #5
#3

Nej. De har samme signatur.
Avatar billede CodingJoe Nybegynder
05. oktober 2012 - 20:38 #6
Hmmm... HentBilSomXmldocument() havde jeg forsøgt med, men jeg forsøger at minimere antallet af metoder, jeg har nemlig tre metoder, hvortil jeg så også skal lave en AsXmlDOcument version.

Ja, jeg vil ikke bruge reflection....

Hele ideen er at jeg vil overlade det til ham, der implementerer mine metoder om han vil have et xmldocument eller almindelig bil objekt...jeg legede lidt med tanken om man kunne løse det med delegates.
Avatar billede CodingJoe Nybegynder
05. oktober 2012 - 20:42 #7
@Janus

Det kan jeg ikke som Arne skriver, så har den samme signatur.

Kan et factory pattern løse det? eller vurderer i det som rent overkill at gøre...
Avatar billede CodingJoe Nybegynder
05. oktober 2012 - 21:33 #8
Leger lidt med generic extension methods...
Avatar billede Syska Mester
05. oktober 2012 - 22:22 #9
Hvis du bare sig at personen skal implementere:

T HentBil<T>(int id)

Så har du jo allerede givet brugeren lov til at implementere det som han vil ... så er du vel i mål.

Det lyder som om du er på vej ud af en helt forkert tangent.
Avatar billede CodingJoe Nybegynder
05. oktober 2012 - 22:30 #10
Det virkede med at lave en generic extension method...som jeg kaldte ToXmlDocument.
Avatar billede CodingJoe Nybegynder
05. oktober 2012 - 22:31 #11
Nopes. Tre linjer kode, og jeg er koerende...
Avatar billede CodingJoe Nybegynder
05. oktober 2012 - 22:35 #12
public static XmlDocument ToXmlDocument<T>(this T entity)
{
    return SerializeHelper.Serialize(entity);
}

Implementering:
var xmlDokument = MinManager.HentEntitet(2).ToXmlDocument();
Avatar billede CodingJoe Nybegynder
05. oktober 2012 - 22:38 #13
Hvad siger du til den loesning Arne? :)
Avatar billede janus_007 Nybegynder
05. oktober 2012 - 22:49 #14
hmm.

public T HentBil<T>(int id) where T : XmlDocument

public T HentBil<T>(int id, bool d = false) where T : Bil

hehe.. så kan du jo bare undlade den optionale :)

Anyway.. du kan da godt lave et factorypattern, men du skal alligevel reflecte lidt eller som Arne skriver spørge på typen.

Hvis du virkelig gerne vil gøre det dynamisk og smart uden at bryde open-closed principle kan jeg måske lave en kodestump til dig hvor du skal bruge Structuremap, men det ved jeg ikke om du vil kaste dig ud i?
Avatar billede CodingJoe Nybegynder
05. oktober 2012 - 22:52 #15
Jo, men jeg har jo allerede loest det ved at lave en generisk extension method.
Avatar billede arne_v Ekspert
06. oktober 2012 - 04:11 #16
Din extension metode er saamaend udmaerket.

Men den har intet at goere med dit API.

Og jeg er tilboejelig til at mene at det slet ikke er dit API som skal tilbyde den, men at du skal lade caller af dit API lave en saadan hvis vedkommende oensker det.

Uden restriction paa T bliver den jo klasket paa alt og hvis alle API'er begynder at tilbyde helt generelle extensions methods, saa bliver det hurtigt noget rod.

public static XmlDocument ToXmlDocument<T>(this T entity) where T : BaseClassOrInterfaceForAllYourClasses

derimod kunne du godt forsvare at have i dit API.
Avatar billede CodingJoe Nybegynder
06. oktober 2012 - 09:21 #17
Mange tak for input Arne, jeg er rigtig glad for du giver mig yderligere fifs til optimering.

Det fortjener helt klart mine points :)

Smid du bare et svar ind her.
Avatar billede CodingJoe Nybegynder
06. oktober 2012 - 09:36 #18
...Dog har jeg et lille spørgsmål. Hvis jeg laver en constraint på et Interface fx.


public static XmlDocument ToXmlDocument<T>(this T entity) where T : IBil

hvad vil der stå i IBil?

Desuden har jeg gjort metoden private og lagt ved siden af mine andre HentBil metoder i min klasse:

private static XmlDocument ToXmlDocument<T>(this T entity) where T : IBil

Hvad siger du til det?
Avatar billede arne_v Ekspert
06. oktober 2012 - 15:40 #19
den skal vel ikke hedde IBil - da den vel skal bruges til andet end bil

IToXmlAble

public interface IToXmlAble
{
}

public class Bil : IToXmlAble
{
...
}

public class Foobar : IToXmlAble
{
...
}

og metoden skal vel vaere public for at kunne bruges

public static XmlDocument ToXmlDocument<T>(this T entity) where T : IToXmlAble
{
...
}

og med en restriction behoever den ikke engang vaere generic:

public static XmlDocument ToXmlDocument(this IToXmlAble entity)
{
...
}
Avatar billede arne_v Ekspert
06. oktober 2012 - 15:41 #20
hvis den kun skal bruges paa bil kan du droppe interface helt
Avatar billede arne_v Ekspert
06. oktober 2012 - 15:41 #21
og et svar
Avatar billede CodingJoe Nybegynder
06. oktober 2012 - 16:03 #22
Jo, men gør jeg den ikke restriktiv ved at gøre den private? Dog ryger generics delen måske lidt, da den bliver private. Jeg kan bedre li' interface versionen, da den også skal bruges på andre klasser.
Avatar billede CodingJoe Nybegynder
06. oktober 2012 - 16:17 #23
Ahh fint læste lige den sidste del af dit svar...
Avatar billede CodingJoe Nybegynder
06. oktober 2012 - 18:38 #24
Jeg har lidt svært ved at finde en god placering af min extension metode. Lige nu ligger den i en BilManager klasse, og den skal jo bruges i andre klasser...hvor synes du, den kan ligge?
Avatar billede arne_v Ekspert
06. oktober 2012 - 19:06 #25
Sin egen klasse evt. sammen med andre extension methods.
Avatar billede Syska Mester
06. oktober 2012 - 20:40 #26
Mange angiver dem som enten:

ExtenstionTo{What ever det nu er extention to}

eller

{What ever det nu er extention to}Extensions

Det gør det nemt altid at finde dem.
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