mirror of
https://github.com/ICDSystems/ICD.Common.Utils.git
synced 2026-02-16 13:15:07 +00:00
Merge branch 'dev' of https://cs-gogs.icdpf.net/Common/Utils into dev
This commit is contained in:
@@ -10,6 +10,14 @@ namespace ICD.Common.Utils.Tests.Extensions
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public sealed class TypeExtensionsTest
|
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(byte), true)]
|
||||||
[TestCase(typeof(decimal), true)]
|
[TestCase(typeof(decimal), true)]
|
||||||
[TestCase(typeof(double), true)]
|
[TestCase(typeof(double), true)]
|
||||||
@@ -61,6 +69,23 @@ namespace ICD.Common.Utils.Tests.Extensions
|
|||||||
Assert.AreEqual(expected, value.IsDecimalNumeric());
|
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(string), typeof(object), true)]
|
||||||
[TestCase(typeof(object), typeof(string), false)]
|
[TestCase(typeof(object), typeof(string), false)]
|
||||||
public void IsAssignableToTest(Type a, Type b, bool expected)
|
public void IsAssignableToTest(Type a, Type b, bool expected)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
<RootNamespace>ICD.Common.Utils.Tests</RootNamespace>
|
<RootNamespace>ICD.Common.Utils.Tests</RootNamespace>
|
||||||
|
<AssemblyName>ICD.Common.Utils.Tests</AssemblyName>
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<Deterministic>true</Deterministic>
|
<Deterministic>true</Deterministic>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -18,7 +19,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
<PackageReference Include="NUnit" Version="3.10.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -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]
|
[Test]
|
||||||
public void MatchesConstructorParametersTest()
|
public void MatchesConstructorParametersTest()
|
||||||
{
|
{
|
||||||
Assert.Throws<ArgumentNullException>(() => ReflectionUtils.MatchesConstructorParameters(null, new object[] { "test", 10 }));
|
Assert.Throws<ArgumentNullException>(() => 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[] {"test", 10}));
|
||||||
Assert.IsTrue(ReflectionUtils.MatchesConstructorParameters(constructor, new object[] {null, 10}));
|
Assert.IsTrue(ReflectionUtils.MatchesConstructorParameters(constructor, new object[] {null, 10}));
|
||||||
@@ -114,6 +103,17 @@ namespace ICD.Common.Utils.Tests
|
|||||||
Assert.NotNull(output);
|
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]
|
[Test]
|
||||||
public void GetCustomAttributesTest()
|
public void GetCustomAttributesTest()
|
||||||
{
|
{
|
||||||
@@ -121,9 +121,33 @@ namespace ICD.Common.Utils.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void LoadAssemblyFromPath()
|
public void LoadAssemblyFromPathTest()
|
||||||
{
|
{
|
||||||
Assert.Inconclusive();
|
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)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1062,12 +1062,14 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
{
|
{
|
||||||
public readonly T value;
|
public readonly T value;
|
||||||
public readonly bool isParsed;
|
public readonly bool isParsed;
|
||||||
|
|
||||||
public TryParseStruct(T value, bool isParsed)
|
public TryParseStruct(T value, bool isParsed)
|
||||||
{
|
{
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.isParsed = isParsed;
|
this.isParsed = isParsed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// since Func<...,T> can't specify `out` parameters
|
// since Func<...,T> can't specify `out` parameters
|
||||||
public delegate bool TryParseDelegate<T>(string input, out T output);
|
public delegate bool TryParseDelegate<T>(string input, out T output);
|
||||||
|
|
||||||
@@ -1079,7 +1081,8 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
/// <param name="extends">enumerable of strings to parse</param>
|
/// <param name="extends">enumerable of strings to parse</param>
|
||||||
/// <param name="tryParseFunc">TryParse function for given type</param>
|
/// <param name="tryParseFunc">TryParse function for given type</param>
|
||||||
/// <returns>enumerable of successfully parsed values</returns>
|
/// <returns>enumerable of successfully parsed values</returns>
|
||||||
public static IEnumerable<T> TryParseSkipFailures<T>(this IEnumerable<string> extends, TryParseDelegate<T> tryParseFunc)
|
public static IEnumerable<T> TryParseSkipFailures<T>(this IEnumerable<string> extends,
|
||||||
|
TryParseDelegate<T> tryParseFunc)
|
||||||
{
|
{
|
||||||
if (extends == null)
|
if (extends == null)
|
||||||
throw new ArgumentNullException("extends");
|
throw new ArgumentNullException("extends");
|
||||||
@@ -1088,13 +1091,13 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
throw new ArgumentNullException("tryParseFunc");
|
throw new ArgumentNullException("tryParseFunc");
|
||||||
|
|
||||||
return extends.Select(str =>
|
return extends.Select(str =>
|
||||||
{
|
{
|
||||||
T value = default(T);
|
T value;
|
||||||
bool isParsed = tryParseFunc(str, out value);
|
bool isParsed = tryParseFunc(str, out value);
|
||||||
return new TryParseStruct<T>(value, isParsed);
|
return new TryParseStruct<T>(value, isParsed);
|
||||||
})
|
})
|
||||||
.Where(v => v.isParsed == true)
|
.Where(v => v.isParsed)
|
||||||
.Select(v => v.value);
|
.Select(v => v.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SIMPLSHARP
|
#if SIMPLSHARP
|
||||||
|
|||||||
@@ -45,6 +45,18 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
typeof(float),
|
typeof(float),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static readonly IcdHashSet<Type> s_IntegerNumericTypes = new IcdHashSet<Type>
|
||||||
|
{
|
||||||
|
typeof(byte),
|
||||||
|
typeof(int),
|
||||||
|
typeof(long),
|
||||||
|
typeof(sbyte),
|
||||||
|
typeof(short),
|
||||||
|
typeof(uint),
|
||||||
|
typeof(ulong),
|
||||||
|
typeof(ushort)
|
||||||
|
};
|
||||||
|
|
||||||
private static readonly Dictionary<Type, Type[]> s_TypeAllTypes;
|
private static readonly Dictionary<Type, Type[]> s_TypeAllTypes;
|
||||||
private static readonly Dictionary<Type, Type[]> s_TypeBaseTypes;
|
private static readonly Dictionary<Type, Type[]> s_TypeBaseTypes;
|
||||||
private static readonly Dictionary<Type, Type[]> s_TypeImmediateInterfaces;
|
private static readonly Dictionary<Type, Type[]> s_TypeImmediateInterfaces;
|
||||||
@@ -61,6 +73,19 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
s_TypeMinimalInterfaces = new Dictionary<Type, Type[]>();
|
s_TypeMinimalInterfaces = new Dictionary<Type, Type[]>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if the given type can represent a null value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="extends"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool CanBeNull(this Type extends)
|
||||||
|
{
|
||||||
|
if (extends == null)
|
||||||
|
throw new ArgumentException("extends");
|
||||||
|
|
||||||
|
return !extends.IsValueType || Nullable.GetUnderlyingType(extends) != null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if the given type is a numeric type.
|
/// Returns true if the given type is a numeric type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -100,6 +125,24 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
return s_DecimalNumericTypes.Contains(extends);
|
return s_DecimalNumericTypes.Contains(extends);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if the given type is an integer numeric type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="extends"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool IsIntegerNumeric(this Type extends)
|
||||||
|
{
|
||||||
|
if (extends == null)
|
||||||
|
throw new ArgumentException("extends");
|
||||||
|
|
||||||
|
return s_IntegerNumericTypes.Contains(extends);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Assembly containing the type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="extends"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static Assembly GetAssembly(this Type extends)
|
public static Assembly GetAssembly(this Type extends)
|
||||||
{
|
{
|
||||||
if (extends == null)
|
if (extends == null)
|
||||||
@@ -114,6 +157,12 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
.Assembly;
|
.Assembly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if the type is assignable to the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="from"></param>
|
||||||
|
/// <param name="to"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static bool IsAssignableTo(this Type from, Type to)
|
public static bool IsAssignableTo(this Type from, Type to)
|
||||||
{
|
{
|
||||||
if (from == null)
|
if (from == null)
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<AssemblyName>ICD.Common.Utils</AssemblyName>
|
<AssemblyName>ICD.Common.Utils</AssemblyName>
|
||||||
<RootNamespace>$(AssemblyName)</RootNamespace>
|
<RootNamespace>$(AssemblyName)</RootNamespace>
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<Deterministic>true</Deterministic>
|
<Deterministic>true</Deterministic>
|
||||||
<Authors>Chris Cameron, Jeff Thompson</Authors>
|
<Authors>Chris Cameron, Jeff Thompson</Authors>
|
||||||
<PackageId>ICD.Common.Utils</PackageId>
|
<PackageId>ICD.Common.Utils</PackageId>
|
||||||
<PackageProjectUrl></PackageProjectUrl>
|
<PackageProjectUrl></PackageProjectUrl>
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Data.SQLite" Version="2.0.1" />
|
<PackageReference Include="Microsoft.Data.SQLite" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.0.4" />
|
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.0.4" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
|
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
|
||||||
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>ICD.Common.Utils</RootNamespace>
|
<RootNamespace>ICD.Common.Utils</RootNamespace>
|
||||||
<AssemblyName>ICD.Common.Utils_SimplSharp</AssemblyName>
|
<AssemblyName>ICD.Common.Utils</AssemblyName>
|
||||||
<ProjectTypeGuids>{0B4745B0-194B-4BB6-8E21-E9057CA92500};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{0B4745B0-194B-4BB6-8E21-E9057CA92500};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<PlatformFamilyName>WindowsCE</PlatformFamilyName>
|
<PlatformFamilyName>WindowsCE</PlatformFamilyName>
|
||||||
<PlatformID>E2BECB1F-8C8C-41ba-B736-9BE7D946A398</PlatformID>
|
<PlatformID>E2BECB1F-8C8C-41ba-B736-9BE7D946A398</PlatformID>
|
||||||
|
|||||||
@@ -14,6 +14,12 @@ namespace ICD.Common.Utils.Json
|
|||||||
/// <param name="serializer">The calling serializer.</param>
|
/// <param name="serializer">The calling serializer.</param>
|
||||||
public sealed override void WriteJson(JsonWriter writer, object value, JsonSerializer 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)
|
if (value == null)
|
||||||
{
|
{
|
||||||
writer.WriteNull();
|
writer.WriteNull();
|
||||||
@@ -45,6 +51,12 @@ namespace ICD.Common.Utils.Json
|
|||||||
public sealed override object ReadJson(JsonReader reader, Type objectType, object existingValue,
|
public sealed override object ReadJson(JsonReader reader, Type objectType, object existingValue,
|
||||||
JsonSerializer serializer)
|
JsonSerializer serializer)
|
||||||
{
|
{
|
||||||
|
if (reader == null)
|
||||||
|
throw new ArgumentNullException("reader");
|
||||||
|
|
||||||
|
if (serializer == null)
|
||||||
|
throw new ArgumentNullException("serializer");
|
||||||
|
|
||||||
return ReadJson(reader, (T)existingValue, serializer);
|
return ReadJson(reader, (T)existingValue, serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ namespace ICD.Common.Utils.Json
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void CacheType(Type type)
|
public static void CacheType(Type type)
|
||||||
{
|
{
|
||||||
|
if (type == null)
|
||||||
|
throw new ArgumentNullException("type");
|
||||||
|
|
||||||
string serialized = JsonConvert.SerializeObject(ReflectionUtils.CreateInstance(type));
|
string serialized = JsonConvert.SerializeObject(ReflectionUtils.CreateInstance(type));
|
||||||
JsonConvert.DeserializeObject(serialized, type);
|
JsonConvert.DeserializeObject(serialized, type);
|
||||||
}
|
}
|
||||||
@@ -91,7 +94,34 @@ namespace ICD.Common.Utils.Json
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public static void Print(string json)
|
public static void Print(string json)
|
||||||
{
|
{
|
||||||
IcdConsole.PrintLine(Format(json));
|
if (json == null)
|
||||||
|
throw new ArgumentNullException("json");
|
||||||
|
|
||||||
|
string formatted = Format(json);
|
||||||
|
IcdConsole.PrintLine(formatted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Serializes the given item and pretty-prints to JSON.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
[PublicAPI]
|
||||||
|
public static void Print(object value)
|
||||||
|
{
|
||||||
|
string formatted = Format(value);
|
||||||
|
IcdConsole.PrintLine(formatted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Serializes the given item and formats the JSON into a human-readable form.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[PublicAPI]
|
||||||
|
public static string Format(object value)
|
||||||
|
{
|
||||||
|
string serial = JsonConvert.SerializeObject(value);
|
||||||
|
return Format(serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -102,6 +132,9 @@ namespace ICD.Common.Utils.Json
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public static string Format(string json)
|
public static string Format(string json)
|
||||||
{
|
{
|
||||||
|
if (json == null)
|
||||||
|
throw new ArgumentNullException("json");
|
||||||
|
|
||||||
int indent = 0;
|
int indent = 0;
|
||||||
bool quoted = false;
|
bool quoted = false;
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
@@ -287,6 +320,12 @@ namespace ICD.Common.Utils.Json
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static object Deserialize(Type type, JToken token)
|
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());
|
return Deserialize(type, token, new JsonSerializer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,6 +338,15 @@ namespace ICD.Common.Utils.Json
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static object Deserialize(Type type, JToken token, JsonSerializer serializer)
|
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))
|
using (JTokenReader jsonReader = new JTokenReader(token))
|
||||||
return serializer.Deserialize(jsonReader, type);
|
return serializer.Deserialize(jsonReader, type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,9 @@ namespace ICD.Common.Utils
|
|||||||
/// <returns>The newly mapped value</returns>
|
/// <returns>The newly mapped value</returns>
|
||||||
public static double MapRange(double inputStart, double inputEnd, double outputStart, double outputEnd, double 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);
|
double slope = (outputEnd - outputStart) / (inputEnd - inputStart);
|
||||||
return outputStart + slope * (value - inputStart);
|
return outputStart + slope * (value - inputStart);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using ICD.Common.Properties;
|
|
||||||
using ICD.Common.Utils.Extensions;
|
using ICD.Common.Utils.Extensions;
|
||||||
using ICD.Common.Utils.IO;
|
using ICD.Common.Utils.IO;
|
||||||
#if SIMPLSHARP
|
#if SIMPLSHARP
|
||||||
@@ -20,41 +19,6 @@ namespace ICD.Common.Utils
|
|||||||
{
|
{
|
||||||
public static class ReflectionUtils
|
public static class ReflectionUtils
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Instantiates the given type using the constructor matching the given values.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type"></param>
|
|
||||||
/// <param name="values"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if the parameters match the constructor parameters.
|
/// Returns true if the parameters match the constructor parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -70,12 +34,13 @@ namespace ICD.Common.Utils
|
|||||||
throw new ArgumentNullException("parameters");
|
throw new ArgumentNullException("parameters");
|
||||||
|
|
||||||
#if SIMPLSHARP
|
#if SIMPLSHARP
|
||||||
IEnumerable<CType> methodTypes
|
IEnumerable<CType>
|
||||||
#else
|
#else
|
||||||
IEnumerable<Type> methodTypes
|
IEnumerable<Type>
|
||||||
#endif
|
#endif
|
||||||
= constructor.GetParameters().Select(p => p.ParameterType);
|
parameterTypes = constructor.GetParameters().Select(p => p.ParameterType);
|
||||||
return ParametersMatchTypes(methodTypes, parameters);
|
|
||||||
|
return ParametersMatchTypes(parameterTypes, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -93,12 +58,13 @@ namespace ICD.Common.Utils
|
|||||||
throw new ArgumentNullException("parameters");
|
throw new ArgumentNullException("parameters");
|
||||||
|
|
||||||
#if SIMPLSHARP
|
#if SIMPLSHARP
|
||||||
IEnumerable<CType> methodTypes
|
IEnumerable<CType>
|
||||||
#else
|
#else
|
||||||
IEnumerable<Type> methodTypes
|
IEnumerable<Type>
|
||||||
#endif
|
#endif
|
||||||
= method.GetParameters().Select(p => p.ParameterType);
|
parameterTypes = method.GetParameters().Select(p => p.ParameterType);
|
||||||
return ParametersMatchTypes(methodTypes, parameters);
|
|
||||||
|
return ParametersMatchTypes(parameterTypes, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -113,11 +79,12 @@ namespace ICD.Common.Utils
|
|||||||
throw new ArgumentNullException("property");
|
throw new ArgumentNullException("property");
|
||||||
|
|
||||||
#if SIMPLSHARP
|
#if SIMPLSHARP
|
||||||
CType propertyType
|
CType
|
||||||
#else
|
#else
|
||||||
Type propertyType
|
Type
|
||||||
#endif
|
#endif
|
||||||
= property.PropertyType;
|
propertyType = property.PropertyType;
|
||||||
|
|
||||||
return ParametersMatchTypes(new[] {propertyType}, new[] {parameter});
|
return ParametersMatchTypes(new[] {propertyType}, new[] {parameter});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,31 +94,41 @@ namespace ICD.Common.Utils
|
|||||||
/// <param name="types"></param>
|
/// <param name="types"></param>
|
||||||
/// <param name="parameters"></param>
|
/// <param name="parameters"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
private static bool ParametersMatchTypes(
|
||||||
#if SIMPLSHARP
|
#if SIMPLSHARP
|
||||||
private static bool ParametersMatchTypes(IEnumerable<CType> types, IEnumerable<object> parameters)
|
IEnumerable<CType>
|
||||||
{
|
|
||||||
if (types == null)
|
|
||||||
throw new ArgumentNullException("types");
|
|
||||||
|
|
||||||
CType[] typesArray = types as CType[] ?? types.ToArray();
|
|
||||||
#else
|
#else
|
||||||
private static bool ParametersMatchTypes(IEnumerable<Type> types, IEnumerable<object> parameters)
|
IEnumerable<Type>
|
||||||
|
#endif
|
||||||
|
types, IEnumerable<object> parameters)
|
||||||
{
|
{
|
||||||
if (types == null)
|
if (types == null)
|
||||||
throw new ArgumentNullException("types");
|
throw new ArgumentNullException("types");
|
||||||
|
|
||||||
Type[] typesArray = types as Type[] ?? types.ToArray();
|
|
||||||
#endif
|
|
||||||
if (parameters == null)
|
if (parameters == null)
|
||||||
throw new ArgumentNullException("parameters");
|
throw new ArgumentNullException("parameters");
|
||||||
|
|
||||||
|
#if SIMPLSHARP
|
||||||
|
CType[]
|
||||||
|
#else
|
||||||
|
Type[]
|
||||||
|
#endif
|
||||||
|
typesArray = types as
|
||||||
|
#if SIMPLSHARP
|
||||||
|
CType[]
|
||||||
|
#else
|
||||||
|
Type[]
|
||||||
|
#endif
|
||||||
|
?? types.ToArray();
|
||||||
|
|
||||||
object[] parametersArray = parameters as object[] ?? parameters.ToArray();
|
object[] parametersArray = parameters as object[] ?? parameters.ToArray();
|
||||||
|
|
||||||
if (parametersArray.Length != typesArray.Length)
|
if (parametersArray.Length != typesArray.Length)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Compares each pair of items in the two arrays.
|
// Compares each pair of items in the two arrays.
|
||||||
return !parametersArray.Where((t, index) => !ParameterMatchesType(typesArray[index], t)).Any();
|
return !parametersArray.Where((t, index) => !ParameterMatchesType(typesArray[index], t))
|
||||||
|
.Any();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -160,50 +137,38 @@ namespace ICD.Common.Utils
|
|||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <param name="parameter"></param>
|
/// <param name="parameter"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
#if SIMPLSHARP
|
private static bool ParameterMatchesType(Type type, object parameter)
|
||||||
private static bool ParameterMatchesType(CType type, object parameter)
|
|
||||||
{
|
{
|
||||||
if (type == null)
|
if (type == null)
|
||||||
throw new ArgumentNullException("type");
|
throw new ArgumentNullException("type");
|
||||||
|
|
||||||
|
#if SIMPLSHARP
|
||||||
// Can the parameter be assigned a null value?
|
// Can the parameter be assigned a null value?
|
||||||
if (parameter == null)
|
if (parameter == null)
|
||||||
return (type.IsClass || !type.IsValueType || Nullable.GetUnderlyingType(type) != null);
|
return (type.IsClass || !type.IsValueType || Nullable.GetUnderlyingType(type) != null);
|
||||||
|
|
||||||
return type.IsInstanceOfType(parameter);
|
return type.IsInstanceOfType(parameter);
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
private static bool ParameterMatchesType(Type type, object parameter)
|
TypeInfo info = type.GetTypeInfo();
|
||||||
{
|
|
||||||
if (type == null)
|
|
||||||
throw new ArgumentNullException("type");
|
|
||||||
|
|
||||||
TypeInfo info = type.GetTypeInfo();
|
|
||||||
// Can the parameter be assigned a null value?
|
// Can the parameter be assigned a null value?
|
||||||
if (parameter == null)
|
if (parameter == null)
|
||||||
return (info.IsClass || !info.IsValueType || Nullable.GetUnderlyingType(type) != null);
|
return (info.IsClass || !info.IsValueType || Nullable.GetUnderlyingType(type) != null);
|
||||||
|
|
||||||
return info.IsInstanceOfType(parameter);
|
return info.IsInstanceOfType(parameter);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Same as doing default(Type).
|
/// Same as doing default(Type).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
#if SIMPLSHARP
|
|
||||||
public static object GetDefaultValue(CType type)
|
|
||||||
#else
|
|
||||||
public static object GetDefaultValue(Type type)
|
public static object GetDefaultValue(Type type)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
if (type == null)
|
if (type == null)
|
||||||
throw new ArgumentNullException("type");
|
throw new ArgumentNullException("type");
|
||||||
|
|
||||||
return type
|
return type
|
||||||
#if !SIMPLSHARP
|
#if !SIMPLSHARP
|
||||||
.GetTypeInfo()
|
.GetTypeInfo()
|
||||||
#endif
|
#endif
|
||||||
.IsValueType
|
.IsValueType
|
||||||
? Activator.CreateInstance(type)
|
? Activator.CreateInstance(type)
|
||||||
@@ -230,34 +195,69 @@ namespace ICD.Common.Utils
|
|||||||
!= null;
|
!= null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Platform independant delegate instantiation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="firstArgument"></param>
|
||||||
|
/// <param name="method"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
#if SIMPLSHARP
|
||||||
|
CDelegate
|
||||||
|
#else
|
||||||
|
Delegate
|
||||||
|
#endif
|
||||||
|
.CreateDelegate(type, firstArgument, method);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an instance of the given type, calling the default constructor.
|
/// Creates an instance of the given type, calling the default constructor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static T CreateInstance<T>()
|
public static T CreateInstance<T>(params object[] parameters)
|
||||||
where T : new()
|
|
||||||
{
|
{
|
||||||
return (T)CreateInstance(typeof(T));
|
if (parameters == null)
|
||||||
|
throw new ArgumentNullException("parameters");
|
||||||
|
|
||||||
|
return (T)CreateInstance(typeof(T), parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an instance of the given type, calling the default constructor.
|
/// Creates an instance of the given type, calling the default constructor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static object CreateInstance(Type type)
|
public static object CreateInstance(Type type, params object[] parameters)
|
||||||
{
|
{
|
||||||
if (type == null)
|
if (type == null)
|
||||||
throw new ArgumentNullException("type");
|
throw new ArgumentNullException("type");
|
||||||
|
|
||||||
|
if (parameters == null)
|
||||||
|
throw new ArgumentNullException("parameters");
|
||||||
|
|
||||||
|
ConstructorInfo constructor =
|
||||||
|
type
|
||||||
|
#if SIMPLSHARP
|
||||||
|
.GetCType()
|
||||||
|
#endif
|
||||||
|
.GetConstructors()
|
||||||
|
.FirstOrDefault(c => MatchesConstructorParameters(c, parameters));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Activator.CreateInstance(type);
|
if (constructor != null)
|
||||||
|
return constructor.Invoke(parameters);
|
||||||
}
|
}
|
||||||
catch (TargetInvocationException e)
|
catch (TypeLoadException e)
|
||||||
{
|
{
|
||||||
throw e.GetBaseException();
|
throw new TypeLoadException(e.GetBaseException().Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string message = string.Format("Unable to find constructor for {0}", type.Name);
|
||||||
|
throw new InvalidOperationException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -335,5 +335,84 @@ namespace ICD.Common.Utils
|
|||||||
: AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
|
: AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the corresponding property info on the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="property"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static PropertyInfo GetImplementation(Type type, PropertyInfo property)
|
||||||
|
{
|
||||||
|
if (type == null)
|
||||||
|
throw new ArgumentNullException("type");
|
||||||
|
|
||||||
|
if (property == null)
|
||||||
|
throw new ArgumentNullException("property");
|
||||||
|
|
||||||
|
if (type.IsInterface)
|
||||||
|
throw new InvalidOperationException("Type must not be an interface");
|
||||||
|
|
||||||
|
property = type
|
||||||
|
#if SIMPLSHARP
|
||||||
|
.GetCType()
|
||||||
|
#else
|
||||||
|
.GetTypeInfo()
|
||||||
|
#endif
|
||||||
|
.GetProperty(property.Name, property.PropertyType);
|
||||||
|
|
||||||
|
if (property == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return property.DeclaringType == type
|
||||||
|
? property
|
||||||
|
: GetImplementation(property.DeclaringType, property);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes the given value to the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static object ChangeType(object value, Type type)
|
||||||
|
{
|
||||||
|
if (type == null)
|
||||||
|
throw new ArgumentNullException("type");
|
||||||
|
|
||||||
|
// Handle null value
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
if (type.CanBeNull())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
throw new InvalidCastException(string.Format("Unable to convert NULL to type {0}", type.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
Type valueType = value.GetType();
|
||||||
|
if (valueType.IsAssignableTo(type))
|
||||||
|
return value;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Handle enum
|
||||||
|
if (type.IsEnum)
|
||||||
|
{
|
||||||
|
if (valueType.IsIntegerNumeric())
|
||||||
|
return Enum.ToObject(type, value);
|
||||||
|
|
||||||
|
if (value is string)
|
||||||
|
return Enum.Parse(type, value as string, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Convert.ChangeType(value, type, null);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
string valueString = valueType.ToString();
|
||||||
|
string message = string.Format("Failed to convert {0} to type {1} - {2}", valueString, type, e.Message);
|
||||||
|
throw new InvalidCastException(message, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user