From 0a656f0058303edee89ba086f1533ee34faad617 Mon Sep 17 00:00:00 2001 From: Chris Cameron Date: Fri, 28 Jul 2017 12:05:49 -0400 Subject: [PATCH] TypeExtension methods for getting base types from a type --- .../Extensions/TypeExtensionsTest.cs | 64 +++++++++++++++++++ ICD.Common.Utils/Extensions/TypeExtensions.cs | 63 ++++++++++++++++-- 2 files changed, 120 insertions(+), 7 deletions(-) create mode 100644 ICD.Common.Utils.Tests/Extensions/TypeExtensionsTest.cs diff --git a/ICD.Common.Utils.Tests/Extensions/TypeExtensionsTest.cs b/ICD.Common.Utils.Tests/Extensions/TypeExtensionsTest.cs new file mode 100644 index 0000000..832ec55 --- /dev/null +++ b/ICD.Common.Utils.Tests/Extensions/TypeExtensionsTest.cs @@ -0,0 +1,64 @@ +using NUnit.Framework; +using System; +using System.Linq; + +namespace ICD.Common.Utils.Extensions +{ + [TestFixture] + public sealed class TypeExtensionsTest + { + [Test] + public void IsAssignableToTest() + { + Assert.IsTrue(typeof(string).IsAssignableTo(typeof(object))); + Assert.IsFalse(typeof(object).IsAssignableTo(typeof(string))); + } + + [Test] + public void GetAllTypesTest() + { + Type[] allTypes = typeof(B).GetAllTypes().ToArray(); + + Assert.AreEqual(6, allTypes.Length); + + Assert.IsTrue(allTypes.Contains(typeof(E))); + Assert.IsTrue(allTypes.Contains(typeof(D))); + Assert.IsTrue(allTypes.Contains(typeof(C))); + Assert.IsTrue(allTypes.Contains(typeof(B))); + Assert.IsTrue(allTypes.Contains(typeof(A))); + Assert.IsTrue(allTypes.Contains(typeof(object))); + } + + [Test] + public void GetBaseTypesTest() + { + Type[] baseTypes = typeof(B).GetBaseTypes().ToArray(); + + Assert.AreEqual(2, baseTypes.Length); + + Assert.IsFalse(baseTypes.Contains(typeof(B))); + Assert.IsTrue(baseTypes.Contains(typeof(A))); + Assert.IsTrue(baseTypes.Contains(typeof(object))); + } + + private interface C + { + } + + private interface D + { + } + + private interface E : C, D + { + } + + private class A + { + } + + private class B : A, E + { + } + } +} \ No newline at end of file diff --git a/ICD.Common.Utils/Extensions/TypeExtensions.cs b/ICD.Common.Utils/Extensions/TypeExtensions.cs index 9dc9246..98e7b0d 100644 --- a/ICD.Common.Utils/Extensions/TypeExtensions.cs +++ b/ICD.Common.Utils/Extensions/TypeExtensions.cs @@ -2,14 +2,63 @@ #if STANDARD using System.Reflection; #endif +using System.Collections.Generic; namespace ICD.Common.Utils.Extensions { - public static class TypeExtensions - { - public static bool IsAssignableTo(this Type from, Type to) - { - return to.IsAssignableFrom(from); - } - } + public static class TypeExtensions + { + public static bool IsAssignableTo(this Type from, Type to) + { + if (from == null) + throw new ArgumentNullException("from"); + + if (to == null) + throw new ArgumentNullException("to"); + + return to.IsAssignableFrom(from); + } + + /// + /// Returns the given type, all base types, and all implemented interfaces. + /// + /// + /// + public static IEnumerable GetAllTypes(this Type extends) + { + if (extends == null) + throw new ArgumentNullException("extends"); + + yield return extends; + + foreach (Type type in extends.GetBaseTypes()) + yield return type; + + foreach (Type type in extends.GetInterfaces()) + yield return type; + } + + /// + /// Returns all base types for the given type. + /// + /// + /// + public static IEnumerable GetBaseTypes(this Type extends) + { + if (extends == null) + throw new ArgumentNullException("extends"); + + do + { + extends = extends +#if !SIMPLSHARP + .GetTypeInfo() +#endif + .BaseType; + + if (extends != null) + yield return extends; + } while (extends != null); + } + } } \ No newline at end of file