2016-05-28 20 views
2

Ich versuche einen object in einen bool Typ zu konvertieren und möchte bool und Nullable<bool> Typen konvertieren. Ich möchte auch sicherstellen, dass ich die passenden Würfe mache, wo es möglich ist. So habe ich den folgenden Code:C# ist Operator mit NULL-Typen immer falsch nach ReSharper

if (value is bool) 
{ 
    boolValue = (bool) value; 
} 
else if (value is bool? && ((bool?)value).HasValue) 
{ 
    boolValue = ((bool?) value).Value; 
} 
else 
{ 
    throw new ArgumentException("Value must be a boolean type"); 
} 

ReSharper 2016 mich darüber informiert, dass value is bool? immer falsch in diesem Stapel, wenn Aussagen auswerten wird. Warum das? Das würde bedeuten, dass Nullable<bool> nicht von object erbt (unmöglich) oder dass value is bool einen bool? erfasst.

Es ist auch möglich, dass ReSharper 2016 einen Fehler hat; Ich sehe, dass die Implementierung von System.Windows.Controls.BooleanToVisibilityConverter.Convert ziemlich identisch ist. Ich bezweifle, dass WPF Core einen solchen Fehler haben würde, was mich zu der Annahme verleitet, dass es ein Problem mit ReSharper ist.

Antwort

6

Wenn ein Werttyp als object gespeichert ist, lautet er boxed. Boxen von Nullable<T> bekommen special treatment:

Objekte basierend auf Nullable Types sind eingerahmt nur dann, wenn das Objekt nicht null ist. Wenn HasValue false ist, wird die Objektreferenz null statt boxen zugewiesen ... Boxing ein Nicht-Null Nullwert Typ Boxen den Wert selbst, nicht die System.Nullable, die den Werttyp umschließt.

Und je die documentation for is:

Ein Ausdruck ergibt wahr, wenn der bereitgestellte Ausdruck nicht-null ist, und das bereitgestellte Objekt kann den bereitgestellten Typen umgewandelt werden, ohne dass eine Ausnahme, die ausgelöst werden soll.

also beides verwenden, können Sie (siehe fiddle), dass in dem Null Fall ableiten:

bool? x = null; 
object obj = x; // assigns obj = null 
obj is bool?  // false, obj is null 
obj is bool  // false, obj is null 

Und in dem Nicht-Null-Fall:

bool? x = true; 
object obj = x; // obj is boxed bool (true) 
obj is bool?  // true, obj unboxes to bool? 
obj is bool  // true, obj unboxes to bool 

So ReSharper sind korrekt: Ihre erste Verzweigung wird als true ausgewertet, wenn valuetrue oder false ist (ob das Objekt von einer bool oderzugewiesen wurde)ist nicht relevant oder sogar bekannt). Der zweite Zweig wird in diesem Fall immer false sein.