Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 53a1fda

Browse files
committed
Improve KVP ConvertTo support
1 parent fcac204 commit 53a1fda

File tree

3 files changed

+79
-7
lines changed

3 files changed

+79
-7
lines changed

src/ServiceStack.Text/AutoMappingUtils.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,25 @@ public static object TryConvertCollections(Type fromType, Type toType, object fr
776776
{
777777
if (fromValue is IEnumerable values)
778778
{
779+
var toEnumObjs = toType == typeof(IEnumerable<object>);
780+
if (typeof(IList).IsAssignableFrom(toType) || toEnumObjs)
781+
{
782+
var to = (IList) (toType.IsArray || toEnumObjs ? new List<object>() : toType.CreateInstance());
783+
var elType = toType.GetCollectionType();
784+
foreach (var item in values)
785+
{
786+
to.Add(elType != null ? item.ConvertTo(elType) : item);
787+
}
788+
if (elType != null && toType.IsArray)
789+
{
790+
var arr = Array.CreateInstance(elType, to.Count);
791+
to.CopyTo(arr, 0);
792+
return arr;
793+
}
794+
795+
return to;
796+
}
797+
779798
if (fromValue is IDictionary d)
780799
{
781800
var obj = toType.CreateInstance();
@@ -784,18 +803,14 @@ public static object TryConvertCollections(Type fromType, Type toType, object fr
784803
case List<KeyValuePair<string, string>> toList: {
785804
foreach (var key in d.Keys)
786805
{
787-
var toKey = key.ConvertTo<string>();
788-
var toValue = d[key].ConvertTo<string>();
789-
toList.Add(new KeyValuePair<string, string>(toKey, toValue));
806+
toList.Add(new KeyValuePair<string, string>(key.ConvertTo<string>(), d[key].ConvertTo<string>()));
790807
}
791808
return toList;
792809
}
793810
case List<KeyValuePair<string, object>> toObjList: {
794811
foreach (var key in d.Keys)
795812
{
796-
var toKey = key.ConvertTo<string>();
797-
var toValue = d[key];
798-
toObjList.Add(new KeyValuePair<string, object>(toKey, toValue));
813+
toObjList.Add(new KeyValuePair<string, object>(key.ConvertTo<string>(), d[key]));
799814
}
800815
return toObjList;
801816
}

src/ServiceStack.Text/PlatformExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ public static bool GetKeyValuePairsTypes(this Type dictType, out Type keyType, o
791791
return false;
792792
}
793793

794-
private static bool GetKeyValuePairTypes(this Type kvpType, out Type keyType, out Type valueType)
794+
public static bool GetKeyValuePairTypes(this Type kvpType, out Type keyType, out Type valueType)
795795
{
796796
var genericKvps = kvpType.GetTypeWithGenericTypeDefinitionOf(typeof(KeyValuePair<,>));
797797
if (genericKvps != null)

tests/ServiceStack.Text.Tests/AutoMappingTests.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,5 +1283,62 @@ public void Can_convert_KVPs_to_ObjectDictionary()
12831283
Assert.That(new[] { strKvp, strKvp2 }.ConvertTo<Dictionary<string,object>>(), Is.EquivalentTo(new Dictionary<string, object> { {"A", "1"}, {"B", "2"} }));
12841284
Assert.That(new[] { intKvp, intKvp2 }.ConvertTo<Dictionary<string,object>>(), Is.EquivalentTo(new Dictionary<string, object> { {"A", 1}, {"B", 2} }));
12851285
}
1286+
1287+
[Test]
1288+
public void Can_convert_between_KVP_Objects_and_IEnumerable()
1289+
{
1290+
var kvps = new List<KeyValuePair<string, object>> {
1291+
new KeyValuePair<string, object>("A", 1),
1292+
new KeyValuePair<string, object>("B", 2),
1293+
new KeyValuePair<string, object>("C", 3),
1294+
};
1295+
1296+
Assert.That(kvps.ConvertTo<IEnumerable<object>>(), Is.EqualTo(kvps));
1297+
Assert.That(kvps.ConvertTo<List<object>>(), Is.EqualTo(kvps));
1298+
Assert.That(kvps.ConvertTo<object[]>(), Is.EqualTo(kvps));
1299+
1300+
List<object> listObjs = kvps.Cast<object>().ToList();
1301+
Assert.That(listObjs.ConvertTo<List<KeyValuePair<string, object>>>(), Is.EquivalentTo(listObjs));
1302+
object[] arrayObjs = kvps.Cast<object>().ToArray();
1303+
Assert.That(arrayObjs.ConvertTo<List<KeyValuePair<string, object>>>(), Is.EquivalentTo(arrayObjs));
1304+
}
1305+
1306+
[Test]
1307+
public void Can_convert_between_KVP_Strings_and_IEnumerable()
1308+
{
1309+
var kvps = new List<KeyValuePair<string, string>> {
1310+
new KeyValuePair<string, string>("A", "1"),
1311+
new KeyValuePair<string, string>("B", "2"),
1312+
new KeyValuePair<string, string>("C", "3"),
1313+
};
1314+
1315+
Assert.That(kvps.ConvertTo<IEnumerable<object>>(), Is.EqualTo(kvps));
1316+
Assert.That(kvps.ConvertTo<List<object>>(), Is.EqualTo(kvps));
1317+
Assert.That(kvps.ConvertTo<object[]>(), Is.EqualTo(kvps));
1318+
1319+
List<object> listObjs = kvps.Cast<object>().ToList();
1320+
Assert.That(listObjs.ConvertTo<List<KeyValuePair<string, object>>>(), Is.EquivalentTo(listObjs));
1321+
object[] arrayObjs = kvps.Cast<object>().ToArray();
1322+
Assert.That(arrayObjs.ConvertTo<List<KeyValuePair<string, object>>>(), Is.EquivalentTo(arrayObjs));
1323+
}
1324+
1325+
[Test]
1326+
public void Can_convert_between_KVP_ints_and_IEnumerable()
1327+
{
1328+
var kvps = new List<KeyValuePair<string, int>> {
1329+
new KeyValuePair<string, int>("A", 1),
1330+
new KeyValuePair<string, int>("B", 2),
1331+
new KeyValuePair<string, int>("C", 3),
1332+
};
1333+
1334+
Assert.That(kvps.ConvertTo<IEnumerable<object>>(), Is.EqualTo(kvps));
1335+
Assert.That(kvps.ConvertTo<List<object>>(), Is.EqualTo(kvps));
1336+
Assert.That(kvps.ConvertTo<object[]>(), Is.EqualTo(kvps));
1337+
1338+
List<object> listObjs = kvps.Cast<object>().ToList();
1339+
Assert.That(listObjs.ConvertTo<List<KeyValuePair<string, object>>>(), Is.EquivalentTo(listObjs));
1340+
object[] arrayObjs = kvps.Cast<object>().ToArray();
1341+
Assert.That(arrayObjs.ConvertTo<List<KeyValuePair<string, object>>>(), Is.EquivalentTo(arrayObjs));
1342+
}
12861343
}
12871344
}

0 commit comments

Comments
 (0)