@@ -374,7 +374,7 @@ private RatingValueHandler()
374374 {
375375 }
376376
377- public static readonly RatingValueHandler Default = new RatingValueHandler ( ) ;
377+ public static readonly RatingValueHandler Default = new ( ) ;
378378
379379 public override RatingValue Parse ( object ? value )
380380 {
@@ -431,7 +431,7 @@ private StringListTypeHandler()
431431 {
432432 }
433433
434- public static readonly StringListTypeHandler Default = new StringListTypeHandler ( ) ;
434+ public static readonly StringListTypeHandler Default = new ( ) ;
435435 //Just a simple List<string> type handler implementation
436436 public override void SetValue ( IDbDataParameter parameter , List < string > ? value )
437437 {
@@ -739,5 +739,130 @@ public Issue461_ParameterisedTypeConstructor(int id, string someValue, Blarg som
739739 public string SomeValue { get ; }
740740 public Blarg SomeBlargValue { get ; }
741741 }
742+
743+ [ Theory ]
744+ [ InlineData ( true ) ]
745+ [ InlineData ( false ) ]
746+ public void Issue1959_TypeHandlerNullability_Subclass ( bool isNull )
747+ {
748+ Issue1959_Subclass_Handler . Register ( ) ;
749+ Issue1959_Subclass ? when = isNull ? null : new ( DateTime . Today ) ;
750+ var whenNotNull = when ?? new ( new DateTime ( 1753 , 1 , 1 ) ) ;
751+
752+ var args = new HazIssue1959_Subclass { Id = 42 , Nullable = when , NonNullable = whenNotNull } ;
753+ var row = connection . QuerySingle < HazIssue1959_Subclass > (
754+ "select @Id as [Id], @NonNullable as [NonNullable], @Nullable as [Nullable]" ,
755+ args ) ;
756+
757+ Assert . NotNull ( row ) ;
758+ Assert . Equal ( 42 , row . Id ) ;
759+ Assert . Equal ( when , row . Nullable ) ;
760+ Assert . Equal ( whenNotNull , row . NonNullable ) ;
761+ }
762+
763+ [ Theory ]
764+ [ InlineData ( true ) ]
765+ [ InlineData ( false ) ]
766+ public void Issue1959_TypeHandlerNullability_Raw ( bool isNull )
767+ {
768+ Issue1959_Raw_Handler . Register ( ) ;
769+ Issue1959_Raw ? when = isNull ? null : new ( DateTime . Today ) ;
770+ var whenNotNull = when ?? new ( new DateTime ( 1753 , 1 , 1 ) ) ;
771+
772+ var args = new HazIssue1959_Raw { Id = 42 , Nullable = when , NonNullable = whenNotNull } ;
773+ var row = connection . QuerySingle < HazIssue1959_Raw > (
774+ "select @Id as [Id], @NonNullable as [NonNullable], @Nullable as [Nullable]" ,
775+ args ) ;
776+
777+ Assert . NotNull ( row ) ;
778+ Assert . Equal ( 42 , row . Id ) ;
779+ Assert . Equal ( when , row . Nullable ) ;
780+ Assert . Equal ( whenNotNull , row . NonNullable ) ;
781+ }
782+
783+ public class HazIssue1959_Subclass
784+ {
785+ public int Id { get ; set ; }
786+ public Issue1959_Subclass NonNullable { get ; set ; }
787+ public Issue1959_Subclass ? Nullable { get ; set ; }
788+ }
789+
790+ public class HazIssue1959_Raw
791+ {
792+ public int Id { get ; set ; }
793+ public Issue1959_Raw NonNullable { get ; set ; }
794+ public Issue1959_Raw ? Nullable { get ; set ; }
795+ }
796+
797+ public class Issue1959_Subclass_Handler : SqlMapper . TypeHandler < Issue1959_Subclass >
798+ {
799+ public static void Register ( ) => SqlMapper . AddTypeHandler < Issue1959_Subclass > ( Instance ) ;
800+ private Issue1959_Subclass_Handler ( ) { }
801+ private static readonly Issue1959_Subclass_Handler Instance = new ( ) ;
802+
803+ public override Issue1959_Subclass Parse ( object value )
804+ {
805+ Assert . NotNull ( value ) ;
806+ Assert . IsType < DateTime > ( value ) ; // checking not DbNull etc
807+ return new Issue1959_Subclass ( ( DateTime ) value ) ;
808+ }
809+ public override void SetValue ( IDbDataParameter parameter , TypeHandlerTests < TProvider > . Issue1959_Subclass value )
810+ => parameter . Value = value . Value ;
811+ }
812+
813+ public class Issue1959_Raw_Handler : SqlMapper . ITypeHandler
814+ {
815+ public static void Register ( ) => SqlMapper . AddTypeHandler ( typeof ( Issue1959_Raw ) , Instance ) ;
816+ private Issue1959_Raw_Handler ( ) { }
817+ private static readonly Issue1959_Raw_Handler Instance = new ( ) ;
818+
819+ void SqlMapper . ITypeHandler . SetValue ( IDbDataParameter parameter , object value )
820+ {
821+ Assert . NotNull ( value ) ;
822+ if ( value is DBNull )
823+ {
824+ parameter . Value = value ;
825+ }
826+ else
827+ {
828+ Assert . IsType < Issue1959_Raw > ( value ) ; // checking not DbNull etc
829+ parameter . Value = ( ( Issue1959_Raw ) value ) . Value ;
830+ }
831+ }
832+ object ? SqlMapper . ITypeHandler . Parse ( Type destinationType , object value )
833+ {
834+ Assert . NotNull ( value ) ;
835+ Assert . IsType < DateTime > ( value ) ; // checking not DbNull etc
836+ return new Issue1959_Raw ( ( DateTime ) value ) ;
837+ }
838+ }
839+
840+ #pragma warning disable CA2231 // Overload operator equals on overriding value type Equals
841+ public readonly struct Issue1959_Subclass : IEquatable < Issue1959_Subclass >
842+ #pragma warning restore CA2231 // Overload operator equals on overriding value type Equals
843+ {
844+ public Issue1959_Subclass ( DateTime value ) => Value = value ;
845+ public readonly DateTime Value ;
846+ public override int GetHashCode ( ) => Value . GetHashCode ( ) ;
847+ public override bool Equals ( object ? obj )
848+ => obj is Issue1959_Subclass other && Equals ( other ) ;
849+ public bool Equals ( Issue1959_Subclass other )
850+ => other . Value == Value ;
851+ public override string ToString ( ) => Value . ToString ( ) ;
852+ }
853+
854+ #pragma warning disable CA2231 // Overload operator equals on overriding value type Equals
855+ public readonly struct Issue1959_Raw : IEquatable < Issue1959_Raw >
856+ #pragma warning restore CA2231 // Overload operator equals on overriding value type Equals
857+ {
858+ public Issue1959_Raw ( DateTime value ) => Value = value ;
859+ public readonly DateTime Value ;
860+ public override int GetHashCode ( ) => Value . GetHashCode ( ) ;
861+ public override bool Equals ( object ? obj )
862+ => obj is Issue1959_Raw other && Equals ( other ) ;
863+ public bool Equals ( Issue1959_Raw other )
864+ => other . Value == Value ;
865+ public override string ToString ( ) => Value . ToString ( ) ;
866+ }
742867 }
743868}
0 commit comments