1414*/
1515
1616using System ;
17+ using System . Collections . Generic ;
18+ using System . Linq ;
1719using MongoDB . Bson . IO ;
1820
1921namespace MongoDB . Bson . Serialization . Serializers
2022{
23+ /// <summary>
24+ /// A factory class for ValueTupleSerializers.
25+ /// </summary>
26+ public static class ValueTupleSerializer
27+ {
28+ /// <summary>
29+ /// Creates a ValueTupleSerializer.
30+ /// </summary>
31+ /// <param name="itemSerializers">The item serializers.</param>
32+ /// <returns>A ValueTupleSerializer.</returns>
33+ public static IBsonSerializer Create ( IEnumerable < IBsonSerializer > itemSerializers )
34+ {
35+ var itemSerializersArray = itemSerializers . ToArray ( ) ;
36+ var valueTupleSerializerType = CreateValueTupleSerializerType ( itemSerializersArray ) ;
37+ return ( IBsonSerializer ) Activator . CreateInstance ( valueTupleSerializerType , itemSerializersArray ) ;
38+
39+ static Type CreateValueTupleSerializerType ( IBsonSerializer [ ] itemSerializersArray )
40+ {
41+ var itemTypes = itemSerializersArray . Select ( s => s . ValueType ) . ToArray ( ) ;
42+ var valueTupleSerializerTypeDefinition = CreateValueTupleSerializerTypeDefinition ( itemTypes . Length ) ;
43+ return valueTupleSerializerTypeDefinition . MakeGenericType ( itemTypes ) ;
44+ }
45+
46+ static Type CreateValueTupleSerializerTypeDefinition ( int itemCount )
47+ {
48+ return itemCount switch
49+ {
50+ 1 => typeof ( ValueTupleSerializer < > ) ,
51+ 2 => typeof ( ValueTupleSerializer < , > ) ,
52+ 3 => typeof ( ValueTupleSerializer < , , > ) ,
53+ 4 => typeof ( ValueTupleSerializer < , , , > ) ,
54+ 5 => typeof ( ValueTupleSerializer < , , , , > ) ,
55+ 6 => typeof ( ValueTupleSerializer < , , , , , > ) ,
56+ 7 => typeof ( ValueTupleSerializer < , , , , , , > ) ,
57+ 8 => typeof ( ValueTupleSerializer < , , , , , , , > ) ,
58+ _ => throw new Exception ( $ "Invalid number of ValueTuple items : { itemCount } .")
59+ } ;
60+ }
61+ }
62+ }
63+
2164 /// <summary>
2265 /// Represents a serializer for a <see cref="ValueTuple{T1}"/>.
2366 /// </summary>
2467 /// <typeparam name="T1">The type of item 1.</typeparam>
25- public sealed class ValueTupleSerializer < T1 > : StructSerializerBase < ValueTuple < T1 > >
68+ public sealed class ValueTupleSerializer < T1 > : StructSerializerBase < ValueTuple < T1 > > , IBsonTupleSerializer
2669 {
2770 // private fields
2871 private readonly Lazy < IBsonSerializer < T1 > > _lazyItem1Serializer ;
@@ -43,7 +86,7 @@ public ValueTupleSerializer()
4386 public ValueTupleSerializer (
4487 IBsonSerializer < T1 > item1Serializer )
4588 {
46- if ( item1Serializer == null ) { throw new ArgumentNullException ( ( nameof ( item1Serializer ) ) ) ; }
89+ if ( item1Serializer == null ) { throw new ArgumentNullException ( nameof ( item1Serializer ) ) ; }
4790
4891 _lazyItem1Serializer = new Lazy < IBsonSerializer < T1 > > ( ( ) => item1Serializer ) ;
4992 }
@@ -101,6 +144,16 @@ public override ValueTuple<T1> Deserialize(BsonDeserializationContext context, B
101144 return new ValueTuple < T1 > ( item1 ) ;
102145 }
103146
147+ /// <inheritdoc/>
148+ public IBsonSerializer GetItemSerializer ( int itemNumber )
149+ {
150+ return itemNumber switch
151+ {
152+ 1 => _lazyItem1Serializer . Value ,
153+ _ => throw new IndexOutOfRangeException ( nameof ( itemNumber ) )
154+ } ;
155+ }
156+
104157 /// <inheritdoc/>
105158 public override void Serialize ( BsonSerializationContext context , BsonSerializationArgs args , ValueTuple < T1 > value )
106159 {
@@ -115,7 +168,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati
115168 /// </summary>
116169 /// <typeparam name="T1">The type of item 1.</typeparam>
117170 /// <typeparam name="T2">The type of item 2.</typeparam>
118- public sealed class ValueTupleSerializer < T1 , T2 > : StructSerializerBase < ValueTuple < T1 , T2 > >
171+ public sealed class ValueTupleSerializer < T1 , T2 > : StructSerializerBase < ValueTuple < T1 , T2 > > , IBsonTupleSerializer
119172 {
120173 // private fields
121174 private readonly Lazy < IBsonSerializer < T1 > > _lazyItem1Serializer ;
@@ -139,7 +192,7 @@ public ValueTupleSerializer(
139192 IBsonSerializer < T1 > item1Serializer ,
140193 IBsonSerializer < T2 > item2Serializer )
141194 {
142- if ( item1Serializer == null ) { throw new ArgumentNullException ( ( nameof ( item1Serializer ) ) ) ; }
195+ if ( item1Serializer == null ) { throw new ArgumentNullException ( nameof ( item1Serializer ) ) ; }
143196 if ( item2Serializer == null ) { throw new ArgumentNullException ( nameof ( item2Serializer ) ) ; }
144197
145198 _lazyItem1Serializer = new Lazy < IBsonSerializer < T1 > > ( ( ) => item1Serializer ) ;
@@ -208,6 +261,17 @@ public override ValueTuple<T1, T2> Deserialize(BsonDeserializationContext contex
208261 return new ValueTuple < T1 , T2 > ( item1 , item2 ) ;
209262 }
210263
264+ /// <inheritdoc/>
265+ public IBsonSerializer GetItemSerializer ( int itemNumber )
266+ {
267+ return itemNumber switch
268+ {
269+ 1 => _lazyItem1Serializer . Value ,
270+ 2 => _lazyItem2Serializer . Value ,
271+ _ => throw new IndexOutOfRangeException ( nameof ( itemNumber ) )
272+ } ;
273+ }
274+
211275 /// <inheritdoc/>
212276 public override void Serialize ( BsonSerializationContext context , BsonSerializationArgs args , ValueTuple < T1 , T2 > value )
213277 {
@@ -224,7 +288,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati
224288 /// <typeparam name="T1">The type of item 1.</typeparam>
225289 /// <typeparam name="T2">The type of item 2.</typeparam>
226290 /// <typeparam name="T3">The type of item 3.</typeparam>
227- public sealed class ValueTupleSerializer < T1 , T2 , T3 > : StructSerializerBase < ValueTuple < T1 , T2 , T3 > >
291+ public sealed class ValueTupleSerializer < T1 , T2 , T3 > : StructSerializerBase < ValueTuple < T1 , T2 , T3 > > , IBsonTupleSerializer
228292 {
229293 // private fields
230294 private readonly Lazy < IBsonSerializer < T1 > > _lazyItem1Serializer ;
@@ -251,7 +315,7 @@ public ValueTupleSerializer(
251315 IBsonSerializer < T2 > item2Serializer ,
252316 IBsonSerializer < T3 > item3Serializer )
253317 {
254- if ( item1Serializer == null ) { throw new ArgumentNullException ( ( nameof ( item1Serializer ) ) ) ; }
318+ if ( item1Serializer == null ) { throw new ArgumentNullException ( nameof ( item1Serializer ) ) ; }
255319 if ( item2Serializer == null ) { throw new ArgumentNullException ( nameof ( item2Serializer ) ) ; }
256320 if ( item3Serializer == null ) { throw new ArgumentNullException ( nameof ( item3Serializer ) ) ; }
257321
@@ -331,6 +395,18 @@ public override ValueTuple<T1, T2, T3> Deserialize(BsonDeserializationContext co
331395 return new ValueTuple < T1 , T2 , T3 > ( item1 , item2 , item3 ) ;
332396 }
333397
398+ /// <inheritdoc/>
399+ public IBsonSerializer GetItemSerializer ( int itemNumber )
400+ {
401+ return itemNumber switch
402+ {
403+ 1 => _lazyItem1Serializer . Value ,
404+ 2 => _lazyItem2Serializer . Value ,
405+ 3 => _lazyItem3Serializer . Value ,
406+ _ => throw new IndexOutOfRangeException ( nameof ( itemNumber ) )
407+ } ;
408+ }
409+
334410 /// <inheritdoc/>
335411 public override void Serialize ( BsonSerializationContext context , BsonSerializationArgs args , ValueTuple < T1 , T2 , T3 > value )
336412 {
@@ -349,7 +425,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati
349425 /// <typeparam name="T2">The type of item 2.</typeparam>
350426 /// <typeparam name="T3">The type of item 3.</typeparam>
351427 /// <typeparam name="T4">The type of item 4.</typeparam>
352- public sealed class ValueTupleSerializer < T1 , T2 , T3 , T4 > : StructSerializerBase < ValueTuple < T1 , T2 , T3 , T4 > >
428+ public sealed class ValueTupleSerializer < T1 , T2 , T3 , T4 > : StructSerializerBase < ValueTuple < T1 , T2 , T3 , T4 > > , IBsonTupleSerializer
353429 {
354430 // private fields
355431 private readonly Lazy < IBsonSerializer < T1 > > _lazyItem1Serializer ;
@@ -470,6 +546,19 @@ public override ValueTuple<T1, T2, T3, T4> Deserialize(BsonDeserializationContex
470546 return new ValueTuple < T1 , T2 , T3 , T4 > ( item1 , item2 , item3 , item4 ) ;
471547 }
472548
549+ /// <inheritdoc/>
550+ public IBsonSerializer GetItemSerializer ( int itemNumber )
551+ {
552+ return itemNumber switch
553+ {
554+ 1 => _lazyItem1Serializer . Value ,
555+ 2 => _lazyItem2Serializer . Value ,
556+ 3 => _lazyItem3Serializer . Value ,
557+ 4 => _lazyItem4Serializer . Value ,
558+ _ => throw new IndexOutOfRangeException ( nameof ( itemNumber ) )
559+ } ;
560+ }
561+
473562 /// <inheritdoc/>
474563 public override void Serialize ( BsonSerializationContext context , BsonSerializationArgs args , ValueTuple < T1 , T2 , T3 , T4 > value )
475564 {
@@ -490,7 +579,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati
490579 /// <typeparam name="T3">The type of item 3.</typeparam>
491580 /// <typeparam name="T4">The type of item 4.</typeparam>
492581 /// <typeparam name="T5">The type of item 5.</typeparam>
493- public sealed class ValueTupleSerializer < T1 , T2 , T3 , T4 , T5 > : StructSerializerBase < ValueTuple < T1 , T2 , T3 , T4 , T5 > >
582+ public sealed class ValueTupleSerializer < T1 , T2 , T3 , T4 , T5 > : StructSerializerBase < ValueTuple < T1 , T2 , T3 , T4 , T5 > > , IBsonTupleSerializer
494583 {
495584 // private fields
496585 private readonly Lazy < IBsonSerializer < T1 > > _lazyItem1Serializer ;
@@ -625,6 +714,20 @@ public override ValueTuple<T1, T2, T3, T4, T5> Deserialize(BsonDeserializationCo
625714 return new ValueTuple < T1 , T2 , T3 , T4 , T5 > ( item1 , item2 , item3 , item4 , item5 ) ;
626715 }
627716
717+ /// <inheritdoc/>
718+ public IBsonSerializer GetItemSerializer ( int itemNumber )
719+ {
720+ return itemNumber switch
721+ {
722+ 1 => _lazyItem1Serializer . Value ,
723+ 2 => _lazyItem2Serializer . Value ,
724+ 3 => _lazyItem3Serializer . Value ,
725+ 4 => _lazyItem4Serializer . Value ,
726+ 5 => _lazyItem5Serializer . Value ,
727+ _ => throw new IndexOutOfRangeException ( nameof ( itemNumber ) )
728+ } ;
729+ }
730+
628731 /// <inheritdoc/>
629732 public override void Serialize ( BsonSerializationContext context , BsonSerializationArgs args , ValueTuple < T1 , T2 , T3 , T4 , T5 > value )
630733 {
@@ -647,7 +750,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati
647750 /// <typeparam name="T4">The type of item 4.</typeparam>
648751 /// <typeparam name="T5">The type of item 5.</typeparam>
649752 /// <typeparam name="T6">The type of item 6.</typeparam>
650- public sealed class ValueTupleSerializer < T1 , T2 , T3 , T4 , T5 , T6 > : StructSerializerBase < ValueTuple < T1 , T2 , T3 , T4 , T5 , T6 > >
753+ public sealed class ValueTupleSerializer < T1 , T2 , T3 , T4 , T5 , T6 > : StructSerializerBase < ValueTuple < T1 , T2 , T3 , T4 , T5 , T6 > > , IBsonTupleSerializer
651754 {
652755 // private fields
653756 private readonly Lazy < IBsonSerializer < T1 > > _lazyItem1Serializer ;
@@ -796,6 +899,21 @@ public override ValueTuple<T1, T2, T3, T4, T5, T6> Deserialize(BsonDeserializati
796899 return new ValueTuple < T1 , T2 , T3 , T4 , T5 , T6 > ( item1 , item2 , item3 , item4 , item5 , item6 ) ;
797900 }
798901
902+ /// <inheritdoc/>
903+ public IBsonSerializer GetItemSerializer ( int itemNumber )
904+ {
905+ return itemNumber switch
906+ {
907+ 1 => _lazyItem1Serializer . Value ,
908+ 2 => _lazyItem2Serializer . Value ,
909+ 3 => _lazyItem3Serializer . Value ,
910+ 4 => _lazyItem4Serializer . Value ,
911+ 5 => _lazyItem5Serializer . Value ,
912+ 6 => _lazyItem6Serializer . Value ,
913+ _ => throw new IndexOutOfRangeException ( nameof ( itemNumber ) )
914+ } ;
915+ }
916+
799917 /// <inheritdoc/>
800918 public override void Serialize ( BsonSerializationContext context , BsonSerializationArgs args , ValueTuple < T1 , T2 , T3 , T4 , T5 , T6 > value )
801919 {
@@ -820,7 +938,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati
820938 /// <typeparam name="T5">The type of item 5.</typeparam>
821939 /// <typeparam name="T6">The type of item 6.</typeparam>
822940 /// <typeparam name="T7">The type of item 7.</typeparam>
823- public sealed class ValueTupleSerializer < T1 , T2 , T3 , T4 , T5 , T6 , T7 > : StructSerializerBase < ValueTuple < T1 , T2 , T3 , T4 , T5 , T6 , T7 > >
941+ public sealed class ValueTupleSerializer < T1 , T2 , T3 , T4 , T5 , T6 , T7 > : StructSerializerBase < ValueTuple < T1 , T2 , T3 , T4 , T5 , T6 , T7 > > , IBsonTupleSerializer
824942 {
825943 // private fields
826944 private readonly Lazy < IBsonSerializer < T1 > > _lazyItem1Serializer ;
@@ -983,6 +1101,22 @@ public override ValueTuple<T1, T2, T3, T4, T5, T6, T7> Deserialize(BsonDeseriali
9831101 return new ValueTuple < T1 , T2 , T3 , T4 , T5 , T6 , T7 > ( item1 , item2 , item3 , item4 , item5 , item6 , item7 ) ;
9841102 }
9851103
1104+ /// <inheritdoc/>
1105+ public IBsonSerializer GetItemSerializer ( int itemNumber )
1106+ {
1107+ return itemNumber switch
1108+ {
1109+ 1 => _lazyItem1Serializer . Value ,
1110+ 2 => _lazyItem2Serializer . Value ,
1111+ 3 => _lazyItem3Serializer . Value ,
1112+ 4 => _lazyItem4Serializer . Value ,
1113+ 5 => _lazyItem5Serializer . Value ,
1114+ 6 => _lazyItem6Serializer . Value ,
1115+ 7 => _lazyItem7Serializer . Value ,
1116+ _ => throw new IndexOutOfRangeException ( nameof ( itemNumber ) )
1117+ } ;
1118+ }
1119+
9861120 /// <inheritdoc/>
9871121 public override void Serialize ( BsonSerializationContext context , BsonSerializationArgs args , ValueTuple < T1 , T2 , T3 , T4 , T5 , T6 , T7 > value )
9881122 {
@@ -1009,7 +1143,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati
10091143 /// <typeparam name="T6">The type of item 6.</typeparam>
10101144 /// <typeparam name="T7">The type of item 7.</typeparam>
10111145 /// <typeparam name="TRest">The type of the rest item.</typeparam>
1012- public sealed class ValueTupleSerializer < T1 , T2 , T3 , T4 , T5 , T6 , T7 , TRest > : StructSerializerBase < ValueTuple < T1 , T2 , T3 , T4 , T5 , T6 , T7 , TRest > >
1146+ public sealed class ValueTupleSerializer < T1 , T2 , T3 , T4 , T5 , T6 , T7 , TRest > : StructSerializerBase < ValueTuple < T1 , T2 , T3 , T4 , T5 , T6 , T7 , TRest > > , IBsonTupleSerializer
10131147 where TRest : struct
10141148 {
10151149 // private fields
@@ -1187,6 +1321,23 @@ public override ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> Deserialize(BsonDe
11871321 return new ValueTuple < T1 , T2 , T3 , T4 , T5 , T6 , T7 , TRest > ( item1 , item2 , item3 , item4 , item5 , item6 , item7 , rest ) ;
11881322 }
11891323
1324+ /// <inheritdoc/>
1325+ public IBsonSerializer GetItemSerializer ( int itemNumber )
1326+ {
1327+ return itemNumber switch
1328+ {
1329+ 1 => _lazyItem1Serializer . Value ,
1330+ 2 => _lazyItem2Serializer . Value ,
1331+ 3 => _lazyItem3Serializer . Value ,
1332+ 4 => _lazyItem4Serializer . Value ,
1333+ 5 => _lazyItem5Serializer . Value ,
1334+ 6 => _lazyItem6Serializer . Value ,
1335+ 7 => _lazyItem7Serializer . Value ,
1336+ 8 => _lazyRestSerializer . Value ,
1337+ _ => throw new IndexOutOfRangeException ( nameof ( itemNumber ) )
1338+ } ;
1339+ }
1340+
11901341 /// <inheritdoc/>
11911342 public override void Serialize ( BsonSerializationContext context , BsonSerializationArgs args , ValueTuple < T1 , T2 , T3 , T4 , T5 , T6 , T7 , TRest > value )
11921343 {
0 commit comments