Es gibt bereits viele gültige Antworten, aber ich würde gerne eine weitere Implementierung als Type-Erweiterung und eine Liste von Unit-Tests hinzufügen, um verschiedene Szenarien zu demonstrieren:
public static class TypeExtensions
{
public static IEnumerable<Type> GetAllTypes(this Type type)
{
var typeInfo = type.GetTypeInfo();
var allTypes = GetAllImplementedTypes(type).Concat(typeInfo.ImplementedInterfaces);
return allTypes;
}
private static IEnumerable<Type> GetAllImplementedTypes(Type type)
{
yield return type;
var typeInfo = type.GetTypeInfo();
var baseType = typeInfo.BaseType;
if (baseType != null)
{
foreach (var foundType in GetAllImplementedTypes(baseType))
{
yield return foundType;
}
}
}
}
Dieser Algorithmus unterstützt die folgenden Szenarien:
public static class GetAllTypesTests
{
public class Given_A_Sample_Standalone_Class_Type_When_Getting_All_Types
: Given_When_Then_Test
{
private Type _sut;
private IEnumerable<Type> _expectedTypes;
private IEnumerable<Type> _result;
protected override void Given()
{
_sut = typeof(SampleStandalone);
_expectedTypes =
new List<Type>
{
typeof(SampleStandalone),
typeof(object)
};
}
protected override void When()
{
_result = _sut.GetAllTypes();
}
[Fact]
public void Then_It_Should_Return_The_Right_Type()
{
_result.Should().BeEquivalentTo(_expectedTypes);
}
}
public class Given_A_Sample_Abstract_Base_Class_Type_When_Getting_All_Types
: Given_When_Then_Test
{
private Type _sut;
private IEnumerable<Type> _expectedTypes;
private IEnumerable<Type> _result;
protected override void Given()
{
_sut = typeof(SampleBase);
_expectedTypes =
new List<Type>
{
typeof(SampleBase),
typeof(object)
};
}
protected override void When()
{
_result = _sut.GetAllTypes();
}
[Fact]
public void Then_It_Should_Return_The_Right_Type()
{
_result.Should().BeEquivalentTo(_expectedTypes);
}
}
public class Given_A_Sample_Child_Class_Type_When_Getting_All_Types
: Given_When_Then_Test
{
private Type _sut;
private IEnumerable<Type> _expectedTypes;
private IEnumerable<Type> _result;
protected override void Given()
{
_sut = typeof(SampleChild);
_expectedTypes =
new List<Type>
{
typeof(SampleChild),
typeof(SampleBase),
typeof(object)
};
}
protected override void When()
{
_result = _sut.GetAllTypes();
}
[Fact]
public void Then_It_Should_Return_The_Right_Type()
{
_result.Should().BeEquivalentTo(_expectedTypes);
}
}
public class Given_A_Sample_Base_Interface_Type_When_Getting_All_Types
: Given_When_Then_Test
{
private Type _sut;
private IEnumerable<Type> _expectedTypes;
private IEnumerable<Type> _result;
protected override void Given()
{
_sut = typeof(ISampleBase);
_expectedTypes =
new List<Type>
{
typeof(ISampleBase)
};
}
protected override void When()
{
_result = _sut.GetAllTypes();
}
[Fact]
public void Then_It_Should_Return_The_Right_Type()
{
_result.Should().BeEquivalentTo(_expectedTypes);
}
}
public class Given_A_Sample_Child_Interface_Type_When_Getting_All_Types
: Given_When_Then_Test
{
private Type _sut;
private IEnumerable<Type> _expectedTypes;
private IEnumerable<Type> _result;
protected override void Given()
{
_sut = typeof(ISampleChild);
_expectedTypes =
new List<Type>
{
typeof(ISampleBase),
typeof(ISampleChild)
};
}
protected override void When()
{
_result = _sut.GetAllTypes();
}
[Fact]
public void Then_It_Should_Return_The_Right_Type()
{
_result.Should().BeEquivalentTo(_expectedTypes);
}
}
public class Given_A_Sample_Implementation_Class_Type_When_Getting_All_Types
: Given_When_Then_Test
{
private Type _sut;
private IEnumerable<Type> _expectedTypes;
private IEnumerable<Type> _result;
protected override void Given()
{
_sut = typeof(SampleImplementation);
_expectedTypes =
new List<Type>
{
typeof(SampleImplementation),
typeof(SampleChild),
typeof(SampleBase),
typeof(ISampleChild),
typeof(ISampleBase),
typeof(object)
};
}
protected override void When()
{
_result = _sut.GetAllTypes();
}
[Fact]
public void Then_It_Should_Return_The_Right_Type()
{
_result.Should().BeEquivalentTo(_expectedTypes);
}
}
public class Given_A_Sample_Interface_Instance_Type_When_Getting_All_Types
: Given_When_Then_Test
{
private Type _sut;
private IEnumerable<Type> _expectedTypes;
private IEnumerable<Type> _result;
class Foo : ISampleChild { }
protected override void Given()
{
var foo = new Foo();
_sut = foo.GetType();
_expectedTypes =
new List<Type>
{
typeof(Foo),
typeof(ISampleChild),
typeof(ISampleBase),
typeof(object)
};
}
protected override void When()
{
_result = _sut.GetAllTypes();
}
[Fact]
public void Then_It_Should_Return_The_Right_Type()
{
_result.Should().BeEquivalentTo(_expectedTypes);
}
}
sealed class SampleStandalone { }
abstract class SampleBase { }
class SampleChild : SampleBase { }
interface ISampleBase { }
interface ISampleChild : ISampleBase { }
class SampleImplementation : SampleChild, ISampleChild { }
}