* ObjectControllerTests.cs: chore: 简化遍历逻辑

* AVObject.cs:
* AVQueryExtensions.cs:
* AVEncoder.cs:
* Conversion.cs:
oneRain 2019-09-18 18:21:28 +08:00
parent e5aa736805
commit 6c62ed2707
5 changed files with 20 additions and 70 deletions

View File

@ -1,4 +1,5 @@
using NUnit.Framework;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
@ -66,10 +67,14 @@ namespace LeanCloud.Test {
obj["content"] = "batch object";
objList.Add(obj);
}
await objList.SaveAllAsync();
objList.ForEach(obj => {
Assert.NotNull(obj.ObjectId);
});
try {
await objList.SaveAllAsync();
objList.ForEach(obj => {
Assert.NotNull(obj.ObjectId);
});
} catch (Exception e) {
TestContext.Out.WriteLine(e.Message);
}
}
[Test]

View File

@ -77,9 +77,6 @@ namespace LeanCloud.Storage.Internal {
private object EncodeList(IList<object> list) {
List<object> newArray = new List<object>();
foreach (object item in list) {
if (!IsValidType(item)) {
throw new ArgumentException("Invalid type for value in an array");
}
newArray.Add(Encode(item));
}
return newArray;

View File

@ -8,6 +8,7 @@ using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using System.Collections;
using System.Linq;
using System.Collections.Concurrent;
namespace LeanCloud {
@ -436,8 +437,7 @@ string propertyName
/// <param name="traverseAVObjects">Whether to traverse into AVObjects' children</param>
/// <param name="yieldRoot">Whether to include the root in the result</param>
/// <returns></returns>
internal static IEnumerable<object> DeepTraversal(
object root, bool traverseAVObjects = false, bool yieldRoot = false) {
internal static IEnumerable<object> DeepTraversal(object root, bool traverseAVObjects = false, bool yieldRoot = false) {
var items = DeepTraversalInternal(root,
traverseAVObjects,
new HashSet<object>(new IdentityEqualityComparer<object>()));
@ -448,22 +448,17 @@ string propertyName
}
}
private static IEnumerable<object> DeepTraversalInternal(
object root, bool traverseAVObjects, ICollection<object> seen) {
private static IEnumerable<object> DeepTraversalInternal(object root, bool traverseAVObjects, ICollection<object> seen) {
seen.Add(root);
var itemsToVisit = isCompiledByIL2CPP ? (System.Collections.IEnumerable)null : (IEnumerable<object>)null;
var dict = Conversion.As<IDictionary<string, object>>(root);
if (dict != null) {
IEnumerable itemsToVisit = null;
if (root is IDictionary dict) {
itemsToVisit = dict.Values;
} else {
var list = Conversion.As<IList<object>>(root);
if (list != null) {
itemsToVisit = list;
} else if (traverseAVObjects) {
var obj = root as AVObject;
if (obj != null) {
itemsToVisit = obj.Keys.ToList().Select(k => obj[k]);
}
} else if (root is IList list) {
itemsToVisit = list;
} else if (traverseAVObjects) {
var obj = root as AVObject;
if (obj != null) {
itemsToVisit = obj.Keys.ToList().Select(k => obj[k]);
}
}
if (itemsToVisit != null) {
@ -1104,11 +1099,6 @@ string propertyName
internal void Set(string key, object value) {
lock (mutex) {
OnSettingValue(ref key, ref value);
if (!AVEncoder.IsValidType(value)) {
throw new ArgumentException("Invalid type for value: " + value.GetType().ToString());
}
PerformOperation(key, new AVSetOperation(value));
}
}

View File

@ -556,12 +556,6 @@ namespace LeanCloud
var fieldPath = GetValue(leftTransformed.Arguments[0]) as string;
var filterValue = GetValue(node.Right);
if (filterValue != null && !AVEncoder.IsValidType(filterValue))
{
throw new InvalidOperationException(
"Where clauses must use types compatible with AVObjects.");
}
switch (node.NodeType)
{
case ExpressionType.GreaterThan:

View File

@ -61,42 +61,6 @@ namespace LeanCloud.Utilities
return (T)Convert.ChangeType(value, typeof(T));
}
if (ReflectionHelpers.IsConstructedGenericType(typeof(T)))
{
// Add lifting for nullables. Only supports conversions between primitives.
if (ReflectionHelpers.IsNullable(typeof(T)))
{
var innerType = ReflectionHelpers.GetGenericTypeArguments(typeof(T))[0];
if (ReflectionHelpers.IsPrimitive(innerType))
{
return (T)Convert.ChangeType(value, innerType);
}
}
Type listType = GetInterfaceType(value.GetType(), typeof(IList<>));
var la = typeof(T).GetGenericTypeDefinition();
var ilb = typeof(IList<>);
var lb = typeof(List<>);
if (listType != null &&
(la == ilb || la == lb))
{
var wrapperType = typeof(FlexibleListWrapper<,>)
.MakeGenericType(ReflectionHelpers.GetGenericTypeArguments(typeof(T))[0],
ReflectionHelpers.GetGenericTypeArguments(listType)[0]);
return Activator.CreateInstance(wrapperType, value);
}
Type dictType = GetInterfaceType(value.GetType(), typeof(IDictionary<,>));
var da = typeof(T).GetGenericTypeDefinition();
var db = typeof(IDictionary<,>);
if (dictType != null &&
da == db)
{
var wrapperType = typeof(FlexibleDictionaryWrapper<,>)
.MakeGenericType(ReflectionHelpers.GetGenericTypeArguments(typeof(T))[1],
ReflectionHelpers.GetGenericTypeArguments(dictType)[1]);
return Activator.CreateInstance(wrapperType, value);
}
}
return value;
}