Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[OO/C#] 1 object of verschillende objecten

Pagina: 1
Acties:

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Hallo,

Ik ben een stukje software aan het ontwikkelen en zit met een waarschijnlijk triviaal probleempje.
Ik zal de situatie proberen te schetsen.

Ik probeer een stukje XML communicatie tussen client en server te encapsuleren.

Ik heb dus een classe met methodes die opdrachten verstuurd en een corresponderende result terug geeft. Om hier ook een eventuele error in terug te kunnen geven, is er een result object bedacht.

Dit result object bestaat uit een error[] property die error objecten bevat.
Nu zijn er 3 verschillende resultaten mogelijk:

- een DataSet
- een Scalar (object)
- een Affected Rows (int)

Nu is mijn vraag concreet:

Moet ik een base classe (ResultBase) die de property error[] bevat, en in de afleidende classes de verschillende Result properties (je kan geen return type overriden anders was het makkelijker geweest)? Of kan ik beter 1 object maken die alle verschillende Results bevat (ze zijn wel wederzijds exclusief, dus als de dataset gevuld is zullen de andere 2 leeg zijn)

De aanroepen die het result object terug geven zijn wel resultaat specifiek, dus als ik een dataset result verwacht zal daar een aparte methode voor zijn, bijvoorbeeld GetDataSetResult() of GetScalarResult().

Ik hoop dat jullie me wat inzicht kunnen geven!

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
ik vind net een oplossing die volgens mij precies is wat ik bedoel, met behulp van generics.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class CommandResult<T>
{
  private Error[] _errors;
  private T _type;

  public virtual T Result
  {
    get {return _type;}
  }
  

  public Error[] Errors
  {
    get { return _errors; }
    set { _errors = value;}    
  }
}

public class DataSetResult : CommandResult<DataSet>
{
        public override DataSet Result
        {
            get
            {
                return base.Result;
            }
        }
}

[ Voor 6% gewijzigd door 4of9 op 25-07-2007 10:13 ]

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • Orphix
  • Registratie: Februari 2000
  • Niet online
Let er wel op dat generics, anders dan de naam vermoedt, juist een specialisatie inhoudt. Oftewel de client die de CommandResult terugkrijgt moet van tevoren specificeren welk type (<T>) het terugkrijgt. Dit hoeft geen probleem te zijn als je zelf je client schrijft en je dus alle controle hebt hierover. Het kan echter wel een problemen vormen wanneer je meer generieke acties wilt doen op CommandResults. Bijvoorbeeld een algemene logger die alle errors opvangt en ze op de console laat zien. De logger zal niet weten wat voor type er is gebruikt en kan dus het CommandResult<T> niet kunnen casten.
Een oplossing hiervoor is om de CommandResult ook een interface te laten implementeren, bijvoorbeeld IErrorCommandResult, waar je de Error[] property in definieert. Nogmaals, niet noodzakelijk maar je kan er in de toekomst tegen aan lopen.

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Dat casten daar liep ik al tegenaan inderdaad. Aangezien we zelf de client schrijven, hebben we de methode waar dat ook op trad generic gemaakt. Daarmee konden we wel casten en werkte het prima.

Hoe zou zo'm probleem zonder generics opgelost kunnen worden (altijd handig om te leren :) )

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • Orphix
  • Registratie: Februari 2000
  • Niet online
4of9 schreef op donderdag 26 juli 2007 @ 08:35:
Dat casten daar liep ik al tegenaan inderdaad. Aangezien we zelf de client schrijven, hebben we de methode waar dat ook op trad generic gemaakt. Daarmee konden we wel casten en werkte het prima.

Hoe zou zo'm probleem zonder generics opgelost kunnen worden (altijd handig om te leren :) )
Het gevaar van generics is dat dit zich als rimpels in het water zich uitspreidt over andere classes in je project. Zo heb je nu je method generiek gemaakt, straks moet je de classe die die method aanroept ook weer generiek maken, etc. Vaak leidt dit tot onnodig complexe code.
Generics kan je zien als een tool om snel een classe te 'genereren': in dit geval maak je eenvoudig drie verschillende soorte classes door de verschillende types op te geven. Maar dan is het wel verstandig om naar de buitenwereld toe een consistente interface aan te bieden. Zoals ik al noemde bijvoorbeeld door het definieren van een interface IErrorResultSet. Een tweede mogelijkheid is het afleiden van een (non-generic) baseclass, maar omdat je code verder weinig overeenkomstige code heeft is een interface aan te raden.

Kijk bijvoorbeeld hoe de collection classes van .NET het doen. Bijvoorbeeld List<T> is een gespecialiseerde container die elementen van een bepaald type kan opslaan. Handig, want scheelt je continu casten en geeft je type-checking tijdens het compileren. Maar het implementeert ook de (non-generic) interface IList, zodat andere onderdelen van het .NET framework, of je eigen programma simpelweg door de lijst heen kunnen itereren zonder dat je het type hoeft te weten.