Da's niet helemaal 'tzelfde; omdat er nu een null meespeelt die 'speciale regels' kent.
Het is heel logisch:
null kun je niet impliciet converteren naar een int of vice versa; exact wat de foutmelding aangeeft.
C#:
1
2
3
| var x = true ? (int?)null : 1;
//of
var x = true ? null : (int?)1; |
Beiden kun je impliciet converteren naar een nullable-int (
int?).
Nu even een voorbeeld zonder null (komen we straks nog even op terug):
C#:
1
2
3
4
5
6
7
8
9
10
| interface IFoo { }
class Foo : IFoo { }
class Bar : Foo { }
class Baz : IFoo { }
var x = true ? new Foo() : new Bar(); // Yay!
var y = true ? new Foo() : new Baz(); // Nope
var z1 = true ? (IFoo)new Foo() : new Baz(); // Yay!
var z2 = true ? new Foo() : (IFoo)new Baz(); // Yay!
var z3 = (IFoo)(true ? new Foo() : new Baz()); // Nope |
Voor x werkt bovenstaand voorbeeld. Bar is namelijk ook een Foo (immers, Bar inherit van Foo).
Voor y werkt het
niet omdat Baz geen Foo is.
Voor z1 en z2 werkt het omdat beiden IFoo implementeren en er dus voor beiden (impliciet) gecast kan worden naar IFoo.
Voor z3 werkt het niet omdat de expressie éérst überhaupt naar iets zal moeten evaluaten voordat het (daarna) gecast kan worden naar IFoo.
Lippert (
eerder aangehaald) vat 't dan ook mooi samen. Wat er
links van de assignment operator (=) staat boeit niet; je moet de expressie namelijk eerst (kunnen) evalueren voordat je kunt assignen en zolang je niet zeker weet welk type de expressie returned heeft 't ook geen nut om te gaan assignen (dus boeie wat 't type
links van de assignment operator is; dat is op dat punt namelijk nog helemaal niet relevant). De "z3 case" demonstreert dat mooi; daar is de IFoo naar de rechterkant van de assignment operator gehaald maar omdat de compiler niet kan bepalen wat er uit de expressie (de ternary tussen de haken) komt weet de compiler ook niet of 'ie kan casten naar IFoo.
Omdat in beide gevallen de rechterkant van de assignment operator duidelijk is; je kunt een null
of een int (pulse) aan testInt toekennen. Null is wat dat betreft misschien een beetje een raar geval; je zou
eigenlijk zoiets "moeten" schrijven (als de compiler niet zo slim was als 'ie is

):
C#:
1
2
3
4
5
6
7
8
9
| int? testInt;
if (pulse == 0)
{
testInt = (int?)null;
}
else
{
testInt = pulse;
} |
En pas je dat toe dan mag de ternary opeens wél:
C#:
1
2
3
| int? testInt = pulse == 0 ? (int?)null : pulse;
//of...
int? testInt = pulse == 0 ? null : (int?)pulse; |
Maar null is toch null?
Nou.. nee... bekijk dit maar eens:
C#:
1
2
3
4
5
6
| int? testInt = true ? (Customer)null : 1; //Nope
// Of het volgende:
var x = (Customer)null;
var y = (int?)null;
int? z1 = x; // Nope
int? z2 = y; // Yay |
[
Voor 44% gewijzigd door
RobIII op 03-12-2015 18:25
]
There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.
Je eigen tweaker.me redirect
Over mij