diff --git a/ICD.Common.Utils.Tests/Extensions/TypeExtensionsTest.cs b/ICD.Common.Utils.Tests/Extensions/TypeExtensionsTest.cs
index 1f8fb59..f6450bb 100644
--- a/ICD.Common.Utils.Tests/Extensions/TypeExtensionsTest.cs
+++ b/ICD.Common.Utils.Tests/Extensions/TypeExtensionsTest.cs
@@ -10,6 +10,14 @@ namespace ICD.Common.Utils.Tests.Extensions
[TestFixture]
public sealed class TypeExtensionsTest
{
+ [TestCase(typeof(byte), false)]
+ [TestCase(typeof(byte?), true)]
+ [TestCase(typeof(string), true)]
+ public void CanBeNullTest(Type value, bool expected)
+ {
+ Assert.AreEqual(expected, value.CanBeNull());
+ }
+
[TestCase(typeof(byte), true)]
[TestCase(typeof(decimal), true)]
[TestCase(typeof(double), true)]
@@ -61,6 +69,23 @@ namespace ICD.Common.Utils.Tests.Extensions
Assert.AreEqual(expected, value.IsDecimalNumeric());
}
+ [TestCase(typeof(byte), true)]
+ [TestCase(typeof(decimal), false)]
+ [TestCase(typeof(double), false)]
+ [TestCase(typeof(float), false)]
+ [TestCase(typeof(int), true)]
+ [TestCase(typeof(long), true)]
+ [TestCase(typeof(sbyte), true)]
+ [TestCase(typeof(short), true)]
+ [TestCase(typeof(uint), true)]
+ [TestCase(typeof(ulong), true)]
+ [TestCase(typeof(ushort), true)]
+ [TestCase(typeof(string), false)]
+ public void IsIntegerNumericTest(Type value, bool expected)
+ {
+ Assert.AreEqual(expected, value.IsIntegerNumeric());
+ }
+
[TestCase(typeof(string), typeof(object), true)]
[TestCase(typeof(object), typeof(string), false)]
public void IsAssignableToTest(Type a, Type b, bool expected)
diff --git a/ICD.Common.Utils.Tests/ICD.Common.Utils.Tests_NetStandard.csproj b/ICD.Common.Utils.Tests/ICD.Common.Utils.Tests_NetStandard.csproj
index 50c6390..4410842 100644
--- a/ICD.Common.Utils.Tests/ICD.Common.Utils.Tests_NetStandard.csproj
+++ b/ICD.Common.Utils.Tests/ICD.Common.Utils.Tests_NetStandard.csproj
@@ -4,6 +4,7 @@
Library
netcoreapp2.0
ICD.Common.Utils.Tests
+ ICD.Common.Utils.Tests
false
true
@@ -18,7 +19,7 @@
-
+
diff --git a/ICD.Common.Utils.Tests/ReflectionUtilsTest.cs b/ICD.Common.Utils.Tests/ReflectionUtilsTest.cs
index 81b34d9..1ba8e18 100644
--- a/ICD.Common.Utils.Tests/ReflectionUtilsTest.cs
+++ b/ICD.Common.Utils.Tests/ReflectionUtilsTest.cs
@@ -34,23 +34,12 @@ namespace ICD.Common.Utils.Tests
}
}
- [TestCase("test", 10)]
- [TestCase(null, 0)]
- public void InstantiateTest(string param1, int param2)
- {
- TestClass result = ReflectionUtils.Instantiate(typeof(TestClass), param1, param2) as TestClass;
-
- Assert.NotNull(result);
- Assert.AreEqual(param1, result.Param1);
- Assert.AreEqual(param2, result.Param2);
- }
-
[Test]
public void MatchesConstructorParametersTest()
{
Assert.Throws(() => ReflectionUtils.MatchesConstructorParameters(null, new object[] { "test", 10 }));
- ConstructorInfo constructor = typeof(TestClass).GetConstructor(new Type[] {typeof(string), typeof(int)});
+ ConstructorInfo constructor = typeof(TestClass).GetConstructor(new[] {typeof(string), typeof(int)});
Assert.IsTrue(ReflectionUtils.MatchesConstructorParameters(constructor, new object[] {"test", 10}));
Assert.IsTrue(ReflectionUtils.MatchesConstructorParameters(constructor, new object[] {null, 10}));
@@ -114,6 +103,17 @@ namespace ICD.Common.Utils.Tests
Assert.NotNull(output);
}
+ [TestCase("test", 10)]
+ [TestCase(null, 0)]
+ public void CreateInstanceTest(string param1, int param2)
+ {
+ TestClass result = ReflectionUtils.CreateInstance(typeof(TestClass), param1, param2) as TestClass;
+
+ Assert.NotNull(result);
+ Assert.AreEqual(param1, result.Param1);
+ Assert.AreEqual(param2, result.Param2);
+ }
+
[Test]
public void GetCustomAttributesTest()
{
@@ -121,9 +121,33 @@ namespace ICD.Common.Utils.Tests
}
[Test]
- public void LoadAssemblyFromPath()
+ public void LoadAssemblyFromPathTest()
{
Assert.Inconclusive();
}
+
+ [Test]
+ public void GetImplementationTest()
+ {
+ Assert.Inconclusive();
+ }
+
+ [Test]
+ public void ChangeTypeTest()
+ {
+ // Same type
+ Assert.AreEqual(10, ReflectionUtils.ChangeType(10, typeof(int)));
+
+ // Null
+ Assert.AreEqual(null, ReflectionUtils.ChangeType(null, typeof(string)));
+
+ // Enums
+ Assert.AreEqual(BindingFlags.GetProperty, ReflectionUtils.ChangeType((int)(object)BindingFlags.GetProperty, typeof(BindingFlags)));
+ Assert.AreEqual(BindingFlags.GetProperty, ReflectionUtils.ChangeType(BindingFlags.GetProperty.ToString(), typeof(BindingFlags)));
+ Assert.AreEqual(BindingFlags.GetProperty, ReflectionUtils.ChangeType(((int)(object)BindingFlags.GetProperty).ToString(), typeof(BindingFlags)));
+
+ // Everything else
+ Assert.AreEqual(10, ReflectionUtils.ChangeType("10", typeof(int)));
+ }
}
}
diff --git a/ICD.Common.Utils/Extensions/EnumerableExtensions.cs b/ICD.Common.Utils/Extensions/EnumerableExtensions.cs
index 3d928ae..74e69ba 100644
--- a/ICD.Common.Utils/Extensions/EnumerableExtensions.cs
+++ b/ICD.Common.Utils/Extensions/EnumerableExtensions.cs
@@ -1062,12 +1062,14 @@ namespace ICD.Common.Utils.Extensions
{
public readonly T value;
public readonly bool isParsed;
+
public TryParseStruct(T value, bool isParsed)
{
this.value = value;
this.isParsed = isParsed;
}
}
+
// since Func<...,T> can't specify `out` parameters
public delegate bool TryParseDelegate(string input, out T output);
@@ -1079,7 +1081,8 @@ namespace ICD.Common.Utils.Extensions
/// enumerable of strings to parse
/// TryParse function for given type
/// enumerable of successfully parsed values
- public static IEnumerable TryParseSkipFailures(this IEnumerable extends, TryParseDelegate tryParseFunc)
+ public static IEnumerable TryParseSkipFailures(this IEnumerable extends,
+ TryParseDelegate tryParseFunc)
{
if (extends == null)
throw new ArgumentNullException("extends");
@@ -1088,13 +1091,13 @@ namespace ICD.Common.Utils.Extensions
throw new ArgumentNullException("tryParseFunc");
return extends.Select(str =>
- {
- T value = default(T);
- bool isParsed = tryParseFunc(str, out value);
- return new TryParseStruct(value, isParsed);
- })
- .Where(v => v.isParsed == true)
- .Select(v => v.value);
+ {
+ T value;
+ bool isParsed = tryParseFunc(str, out value);
+ return new TryParseStruct(value, isParsed);
+ })
+ .Where(v => v.isParsed)
+ .Select(v => v.value);
}
#if SIMPLSHARP
diff --git a/ICD.Common.Utils/Extensions/TypeExtensions.cs b/ICD.Common.Utils/Extensions/TypeExtensions.cs
index ad0a70d..34829aa 100644
--- a/ICD.Common.Utils/Extensions/TypeExtensions.cs
+++ b/ICD.Common.Utils/Extensions/TypeExtensions.cs
@@ -45,6 +45,18 @@ namespace ICD.Common.Utils.Extensions
typeof(float),
};
+ private static readonly IcdHashSet s_IntegerNumericTypes = new IcdHashSet
+ {
+ typeof(byte),
+ typeof(int),
+ typeof(long),
+ typeof(sbyte),
+ typeof(short),
+ typeof(uint),
+ typeof(ulong),
+ typeof(ushort)
+ };
+
private static readonly Dictionary s_TypeAllTypes;
private static readonly Dictionary s_TypeBaseTypes;
private static readonly Dictionary s_TypeImmediateInterfaces;
@@ -61,6 +73,19 @@ namespace ICD.Common.Utils.Extensions
s_TypeMinimalInterfaces = new Dictionary();
}
+ ///
+ /// Returns true if the given type can represent a null value.
+ ///
+ ///
+ ///
+ public static bool CanBeNull(this Type extends)
+ {
+ if (extends == null)
+ throw new ArgumentException("extends");
+
+ return !extends.IsValueType || Nullable.GetUnderlyingType(extends) != null;
+ }
+
///
/// Returns true if the given type is a numeric type.
///
@@ -100,6 +125,24 @@ namespace ICD.Common.Utils.Extensions
return s_DecimalNumericTypes.Contains(extends);
}
+ ///
+ /// Returns true if the given type is an integer numeric type.
+ ///
+ ///
+ ///
+ public static bool IsIntegerNumeric(this Type extends)
+ {
+ if (extends == null)
+ throw new ArgumentException("extends");
+
+ return s_IntegerNumericTypes.Contains(extends);
+ }
+
+ ///
+ /// Gets the Assembly containing the type.
+ ///
+ ///
+ ///
public static Assembly GetAssembly(this Type extends)
{
if (extends == null)
@@ -114,6 +157,12 @@ namespace ICD.Common.Utils.Extensions
.Assembly;
}
+ ///
+ /// Returns true if the type is assignable to the given type.
+ ///
+ ///
+ ///
+ ///
public static bool IsAssignableTo(this Type from, Type to)
{
if (from == null)
diff --git a/ICD.Common.Utils/ICD.Common.Utils_NetStandard.csproj b/ICD.Common.Utils/ICD.Common.Utils_NetStandard.csproj
index 9477e03..8837802 100644
--- a/ICD.Common.Utils/ICD.Common.Utils_NetStandard.csproj
+++ b/ICD.Common.Utils/ICD.Common.Utils_NetStandard.csproj
@@ -5,8 +5,8 @@
netstandard2.0
ICD.Common.Utils
$(AssemblyName)
- false
- true
+ false
+ true
Chris Cameron, Jeff Thompson
ICD.Common.Utils
@@ -44,7 +44,7 @@
-
+
diff --git a/ICD.Common.Utils/ICD.Common.Utils_SimplSharp.csproj b/ICD.Common.Utils/ICD.Common.Utils_SimplSharp.csproj
index 52ac708..63af157 100644
--- a/ICD.Common.Utils/ICD.Common.Utils_SimplSharp.csproj
+++ b/ICD.Common.Utils/ICD.Common.Utils_SimplSharp.csproj
@@ -8,7 +8,7 @@
Library
Properties
ICD.Common.Utils
- ICD.Common.Utils_SimplSharp
+ ICD.Common.Utils
{0B4745B0-194B-4BB6-8E21-E9057CA92500};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
WindowsCE
E2BECB1F-8C8C-41ba-B736-9BE7D946A398
diff --git a/ICD.Common.Utils/Json/AbstractGenericJsonConverter.cs b/ICD.Common.Utils/Json/AbstractGenericJsonConverter.cs
index 31a2a6e..151a7ca 100644
--- a/ICD.Common.Utils/Json/AbstractGenericJsonConverter.cs
+++ b/ICD.Common.Utils/Json/AbstractGenericJsonConverter.cs
@@ -14,6 +14,12 @@ namespace ICD.Common.Utils.Json
/// The calling serializer.
public sealed override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
+ if (writer == null)
+ throw new ArgumentNullException("writer");
+
+ if (serializer == null)
+ throw new ArgumentNullException("serializer");
+
if (value == null)
{
writer.WriteNull();
@@ -45,6 +51,12 @@ namespace ICD.Common.Utils.Json
public sealed override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
+ if (reader == null)
+ throw new ArgumentNullException("reader");
+
+ if (serializer == null)
+ throw new ArgumentNullException("serializer");
+
return ReadJson(reader, (T)existingValue, serializer);
}
diff --git a/ICD.Common.Utils/Json/JsonUtils.cs b/ICD.Common.Utils/Json/JsonUtils.cs
index dcb456d..6449cd7 100644
--- a/ICD.Common.Utils/Json/JsonUtils.cs
+++ b/ICD.Common.Utils/Json/JsonUtils.cs
@@ -37,6 +37,9 @@ namespace ICD.Common.Utils.Json
///
public static void CacheType(Type type)
{
+ if (type == null)
+ throw new ArgumentNullException("type");
+
string serialized = JsonConvert.SerializeObject(ReflectionUtils.CreateInstance(type));
JsonConvert.DeserializeObject(serialized, type);
}
@@ -91,7 +94,34 @@ namespace ICD.Common.Utils.Json
[PublicAPI]
public static void Print(string json)
{
- IcdConsole.PrintLine(Format(json));
+ if (json == null)
+ throw new ArgumentNullException("json");
+
+ string formatted = Format(json);
+ IcdConsole.PrintLine(formatted);
+ }
+
+ ///
+ /// Serializes the given item and pretty-prints to JSON.
+ ///
+ ///
+ [PublicAPI]
+ public static void Print(object value)
+ {
+ string formatted = Format(value);
+ IcdConsole.PrintLine(formatted);
+ }
+
+ ///
+ /// Serializes the given item and formats the JSON into a human-readable form.
+ ///
+ ///
+ ///
+ [PublicAPI]
+ public static string Format(object value)
+ {
+ string serial = JsonConvert.SerializeObject(value);
+ return Format(serial);
}
///
@@ -102,6 +132,9 @@ namespace ICD.Common.Utils.Json
[PublicAPI]
public static string Format(string json)
{
+ if (json == null)
+ throw new ArgumentNullException("json");
+
int indent = 0;
bool quoted = false;
StringBuilder sb = new StringBuilder();
@@ -287,6 +320,12 @@ namespace ICD.Common.Utils.Json
///
public static object Deserialize(Type type, JToken token)
{
+ if (type == null)
+ throw new ArgumentNullException("type");
+
+ if (token == null)
+ throw new ArgumentNullException("token");
+
return Deserialize(type, token, new JsonSerializer());
}
@@ -299,6 +338,15 @@ namespace ICD.Common.Utils.Json
///
public static object Deserialize(Type type, JToken token, JsonSerializer serializer)
{
+ if (type == null)
+ throw new ArgumentNullException("type");
+
+ if (token == null)
+ throw new ArgumentNullException("token");
+
+ if (serializer == null)
+ throw new ArgumentNullException("serializer");
+
using (JTokenReader jsonReader = new JTokenReader(token))
return serializer.Deserialize(jsonReader, type);
}
diff --git a/ICD.Common.Utils/MathUtils.cs b/ICD.Common.Utils/MathUtils.cs
index 26b9258..7d718fd 100644
--- a/ICD.Common.Utils/MathUtils.cs
+++ b/ICD.Common.Utils/MathUtils.cs
@@ -71,6 +71,9 @@ namespace ICD.Common.Utils
/// The newly mapped value
public static double MapRange(double inputStart, double inputEnd, double outputStart, double outputEnd, double value)
{
+ if (inputStart.Equals(inputEnd))
+ throw new DivideByZeroException();
+
double slope = (outputEnd - outputStart) / (inputEnd - inputStart);
return outputStart + slope * (value - inputStart);
}
diff --git a/ICD.Common.Utils/ReflectionUtils.cs b/ICD.Common.Utils/ReflectionUtils.cs
index 76b182b..1260bb6 100644
--- a/ICD.Common.Utils/ReflectionUtils.cs
+++ b/ICD.Common.Utils/ReflectionUtils.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using ICD.Common.Properties;
using ICD.Common.Utils.Extensions;
using ICD.Common.Utils.IO;
#if SIMPLSHARP
@@ -20,41 +19,6 @@ namespace ICD.Common.Utils
{
public static class ReflectionUtils
{
- ///
- /// Instantiates the given type using the constructor matching the given values.
- ///
- ///
- ///
- ///
- [PublicAPI]
- public static object Instantiate(Type type, params object[] values)
- {
- if (type == null)
- throw new ArgumentNullException("type");
-
- ConstructorInfo constructor =
-#if SIMPLSHARP
- ((CType)type)
-#else
- type
-#endif
- .GetConstructors()
- .FirstOrDefault(c => MatchesConstructorParameters(c, values));
-
- try
- {
- if (constructor != null)
- return constructor.Invoke(values);
- }
- catch (TypeLoadException e)
- {
- throw new TypeLoadException(e.GetBaseException().Message);
- }
-
- string message = string.Format("Unable to find constructor for {0}", type.Name);
- throw new InvalidOperationException(message);
- }
-
///
/// Returns true if the parameters match the constructor parameters.
///
@@ -70,12 +34,13 @@ namespace ICD.Common.Utils
throw new ArgumentNullException("parameters");
#if SIMPLSHARP
- IEnumerable methodTypes
+ IEnumerable
#else
- IEnumerable methodTypes
+ IEnumerable
#endif
- = constructor.GetParameters().Select(p => p.ParameterType);
- return ParametersMatchTypes(methodTypes, parameters);
+ parameterTypes = constructor.GetParameters().Select(p => p.ParameterType);
+
+ return ParametersMatchTypes(parameterTypes, parameters);
}
///
@@ -93,12 +58,13 @@ namespace ICD.Common.Utils
throw new ArgumentNullException("parameters");
#if SIMPLSHARP
- IEnumerable methodTypes
+ IEnumerable
#else
- IEnumerable methodTypes
+ IEnumerable
#endif
- = method.GetParameters().Select(p => p.ParameterType);
- return ParametersMatchTypes(methodTypes, parameters);
+ parameterTypes = method.GetParameters().Select(p => p.ParameterType);
+
+ return ParametersMatchTypes(parameterTypes, parameters);
}
///
@@ -113,11 +79,12 @@ namespace ICD.Common.Utils
throw new ArgumentNullException("property");
#if SIMPLSHARP
- CType propertyType
+ CType
#else
- Type propertyType
+ Type
#endif
- = property.PropertyType;
+ propertyType = property.PropertyType;
+
return ParametersMatchTypes(new[] {propertyType}, new[] {parameter});
}
@@ -127,31 +94,41 @@ namespace ICD.Common.Utils
///
///
///
+ private static bool ParametersMatchTypes(
#if SIMPLSHARP
- private static bool ParametersMatchTypes(IEnumerable types, IEnumerable