[C#] gebruik van type conversions

Pagina: 1
Acties:

  • CaptBiele
  • Registratie: Juni 2002
  • Laatst online: 27-08-2021

CaptBiele

No Worries!

Topicstarter
Ik ben benieuwd wat nu de beste implementaties van type conversions zijn. Als voorbeeld neem ik de "string", gezien ik bij dit geval het meeste twijfel.

Voor mij valt een cast met
C#:
1
(string) Foo

uberhaupt buiten de boot, omdat Foo van het type System.String moet zijn. Anders werkt het niet. (wellicht kan dit voor anderen weer een reden zijn om het wel te gebruiken, omdat de exceptie dan verwerkt kan worden).

Meestal gebruik ik zelf de ToString() methode, omdat ik die het netst vind:
C#:
1
Foo.ToString( )

Alleen lees ik hier dat deze methode duurder is.

Wellicht moet ik deze meer gaan gebruiken:
C#:
1
Convert.ToString( Foo )

Omdat deze beter omgaat met null values.

Ik ben benieuwd hoe jullie het gebruiken...

  • whoami
  • Registratie: December 2000
  • Laatst online: 07:13
Het hangt ervan af wat je wilt converten/casten. Als het om reference types gaat, gebruik ik vrijwel altijd de as operator.
De Convert.Toxxx kan je enkel gebruiken als het type IConvertable implementeert.
Value types casten doe ik altijd volgens de gewone cast manier; jouw eerste voorbeeld dus. De ToString() method kan je ook niet altijd gebruiken; het hangt ervan af hoe die ToString method precies geimplementeerd is.

https://fgheysels.github.io/


Verwijderd

Inderdaad, de ToString methode zou ik niet gebruiken, deze is zo implementatie afhankelijk dat je er niet van uit kan gaan dat je wil wat je krijgt (als je een project met meerdere mensen hebt). Mensen kunnen het bv voor gui databinding gebruiken.

Verder doe ik het ook op jou eerste manier, met een try catch.

  • whoami
  • Registratie: December 2000
  • Laatst online: 07:13
Verwijderd schreef op zondag 23 april 2006 @ 16:21:
Mensen kunnen het bv voor gui databinding gebruiken.
Dit zou wel heel evil zijn...
Verder doe ik het ook op jou eerste manier, met een try catch.
Tja... Die try / catch doe ik niet.
Als je zeker weet dat je een string moet hebben, of zult krijgen , dan is dat niet nodig.

Aan de andere kant: stel je wilt 'iets' naar een integer casten, en je weet niet zeker dat je wel een geldig numeriek getal zult krijgen, dan gebruik ik altijd Double.TryParse of Int32.TryParse, of iets dergelijks.

https://fgheysels.github.io/


  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

@whoami
Het is in dat geval veiliger om het is keyword te gebruiken. Dan weet je zeker of het type overeen komt. Voor Double.TryParse moet je namelijk eerst naar string en dan naar (als het te parsen is) een double/int/whatever

Ik ben even aan het testen gegaan en het volgende valt mij op:
C#:
1
2
3
static void ExplicitCast(string s) {
    Console.WriteLine((string)s);
}

levert de volgende IL (alleen relevante code)
code:
1
call       void [mscorlib]System.Console::WriteLine(string)

Zoals te zien wordt er niet eens gecast, oftewel de C# compiler is slim genoeg om te zien dat s al een string is en dat casten dus geen zin heeft.

Voor de <klasse>.ToString() methode geldt dat die altijd wordt aangeroepen. Als je een Console.WriteLine met een klasse doet zal de CLR altijd <klasse>.ToString() aanroepen.
Voorbeeld:
C#:
1
2
3
static void ToStringTest(TestKlasse k) {
    Console.WriteLine(k);
}

levert de volgende IL
code:
1
call       void [mscorlib]System.Console::WriteLine(object)

Wat hier opvalt is dat er een object wordt doorgegeven. De CLR kijkt vervolgens of de klasse een ToString() method implementeerd en zo ja dan zal deze worden gebruikt. Is dit niet het geval dan zal de CLR automatisch het volgende aanroepen:
C#:
1
this.GetType().FullName

wat de naam van de klasse oplevert. Nu is het dus zo dat dit relatief duur is omdat er gekeken moet worden of er al een <klasse>.ToString() bestaat en zo nee dan moet via reflectie het type bepaald worden etc etc.
Het is IMHO dus beter om <klasse>.ToString() te gebruiken als je zeker weet dat die bestaat omdat het iets goedkoper is en _altijd_ bestaat.

Overigens is het wel zo dat het gebruik van System.Convert erg veilig is omdat die altijd exceptions gooit als het fout gaat (overflows, underflows en foute data), maar hier geldt weer dat er exceptions gegooid worden en die zijn duur.

@whoami
Sorry, had nog wat extra dingetjes gevonden :)

[ Voor 81% gewijzigd door MTWZZ op 23-04-2006 20:01 ]

Nu met Land Rover Series 3 en Defender 90


  • whoami
  • Registratie: December 2000
  • Laatst online: 07:13
MTWZZ schreef op zondag 23 april 2006 @ 19:36:
@whoami
Het is in dat geval veiliger om het is keyword te gebruiken.
As is even veilig. Als de conversie niet lukt, dan krijg je gewoon een null reference terug, en dan moet je daar gewoon op checken. Zo spaar je een extra cast uit.
Als je is gebruik moet je dit doen:
code:
1
2
3
4
if( theObject is MyClass )
{
   bliep = (MyClass)theObject;
}

Op die manier moet je dus en een 'dure' check doen (is), en een cast doen.
Met as doe je gewoon zo:
code:
1
2
3
4
5
bliep = theObject as MyClass;
if( bliep == null )
{
    throw new AppllicationException();
}
Voor Double.TryParse moet je namelijk eerst naar string en dan naar (als het te parsen is) een double/int/whatever
Ik had het over reference types (over die as).
Met TryParse had ik het over conversie string -> numeriek.

https://fgheysels.github.io/


  • CaptBiele
  • Registratie: Juni 2002
  • Laatst online: 27-08-2021

CaptBiele

No Worries!

Topicstarter
whoami schreef op zondag 23 april 2006 @ 15:59:
Het hangt ervan af wat je wilt converten/casten. Als het om reference types gaat, gebruik ik vrijwel altijd de as operator.
De Convert.Toxxx kan je enkel gebruiken als het type IConvertable implementeert.
Value types casten doe ik altijd volgens de gewone cast manier; jouw eerste voorbeeld dus. De ToString() method kan je ook niet altijd gebruiken; het hangt ervan af hoe die ToString method precies geimplementeerd is.
Ik neem aan dat toch wel veel typen IConvertable implementeren.
Verder denk ik dat het niet vaak zal voorkomen dat de ToString( ) een implementatie heeft die je niet wilt gebruiken. Je implementeert hem toch alleen als je zeker weet dat het geen nadelige gevolgen heeft? Anders zou ik er een aparte functie voor schrijven.
Maar die 'as' is wellicht ook wel handig ja. Die gebruik ik eigenlijk nooit....
Verwijderd schreef op zondag 23 april 2006 @ 16:21:
Verder doe ik het ook op jou eerste manier, met een try catch.
Nou juist vanwege die try catch, wil ik de eerste methode vermijden. Ik vind het op een of andere manier niet netjes...
whoami schreef op zondag 23 april 2006 @ 19:56:
Met as doe je gewoon zo:
code:
1
2
3
4
5
bliep = theObject as MyClass;
if( bliep == null )
{
    throw new AppllicationException();
}
Maar omdat je hier alsnog een exceptie gooit, wat is dan het verschil met de try catch tassadar? Het feit dat je nog niet zeker weet wat welk type je moet verwachten?
En gebruik je helemaal geen Convert.ToString( )?

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 07:43

gorgi_19

Kruimeltjes zijn weer op :9

Verder denk ik dat het niet vaak zal voorkomen dat de ToString( ) een implementatie heeft die je niet wilt gebruiken.
Mja.. afaik komt het geregeld voor dat het een Me.GetType.ToString() teruggeeft; normaliter heb je daar dus niets aan. Afaik is dit eerder regel dan uitzondering bij value types :) Sowieso houdt ToString afaik ook geen rekening met de Culture, dus zal je gebruik moeten maken van de overloaded method.
CaptBiele schreef op zondag 23 april 2006 @ 21:13:
Maar omdat je hier alsnog een exceptie gooit, wat is dan het verschil met de try catch tassadar?
Je hebt uberhaupt geen try statement en hebt hier dus ook niet de penalty van :) try-catch statements zijn relatief duur en dit voorkom je.
Wat hier opvalt is dat er een object wordt doorgegeven. De CLR kijkt vervolgens of de klasse een ToString() method implementeerd en zo ja dan zal deze worden gebruikt. Is dit niet het geval dan zal de CLR automatisch het volgende aanroepen:
Zo vreemd is dat niet, aangezien ToString een overridable method is van Object. Qua performance hoef je trouwens ook niet wakker te liggen, Me.GetType is een van de goedkoopste methoden op het gebied van reflection met nauwelijks een penalty. :)

[ Voor 67% gewijzigd door gorgi_19 op 23-04-2006 23:16 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • whoami
  • Registratie: December 2000
  • Laatst online: 07:13
gorgi_19 schreef op zondag 23 april 2006 @ 23:00:
[...]

Je hebt uberhaupt geen try statement en hebt hier dus ook niet de penalty van :) try-catch statements zijn relatief duur en dit voorkom je.
Een throw statement is duur.

https://fgheysels.github.io/


  • CaptBiele
  • Registratie: Juni 2002
  • Laatst online: 27-08-2021

CaptBiele

No Worries!

Topicstarter
whoami schreef op maandag 24 april 2006 @ 09:09:
[...]
Een throw statement is duur.
psies. Dus dat maakt qua performance niets uit.... toch :|

  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

Mja.. afaik komt het geregeld voor dat het een Me.GetType.ToString() teruggeeft; normaliter heb je daar dus niets aan. Afaik is dit eerder regel dan uitzondering bij value types :) Sowieso houdt ToString afaik ook geen rekening met de Culture
ToString doet wel aan cultures maar die wordt als je geen formatter/culture uit de huidige thread getrokken.

[ Voor 13% gewijzigd door MTWZZ op 24-04-2006 09:35 ]

Nu met Land Rover Series 3 en Defender 90

Pagina: 1