The method name clearly originates from the reflection API method Type.IsAssignableFrom(Type) used to implement it - and to be fair, this API is also confusing in the sense that I generally have to think about the order of operands.
IsAssignableFrom works as an infix operator (which it technically is as an instance method), however the assertion:
Assert.IsAssignableFrom<TExpected>(actual);
asserts that the actual value is a subtype of TExpected (typeof(TExpected).IsAssignableFrom(actual.GetType()) - a reasonable translation); however it reads as "is assignable from the expected type to the type of the actual value", which actually suggests the opposite type ordering relationship.
IsAssignableTo would actually technically work in this scenario, however I would suggest abandoning the entire IsAssignable naming scheme in favor of a clearer assertion called IsSubtype (to match IsType). You could also consider adding IsProperSubtype, as well as IsSupertype and IsProperSupertype (although the utility of supertype assertions feels much lower).
Edit: perhaps the most succinct explanation of the issue is that the assertion implictly reads as follows:
Assert.IsAssignableFrom<TExpected>(to: actual);
The method name clearly originates from the reflection API method Type.IsAssignableFrom(Type) used to implement it - and to be fair, this API is also confusing in the sense that I generally have to think about the order of operands.
IsAssignableFrom works as an infix operator (which it technically is as an instance method), however the assertion:
asserts that the actual value is a subtype of TExpected (
typeof(TExpected).IsAssignableFrom(actual.GetType())- a reasonable translation); however it reads as "is assignable from the expected type to the type of the actual value", which actually suggests the opposite type ordering relationship.IsAssignableTo would actually technically work in this scenario, however I would suggest abandoning the entire IsAssignable naming scheme in favor of a clearer assertion called IsSubtype (to match IsType). You could also consider adding IsProperSubtype, as well as IsSupertype and IsProperSupertype (although the utility of supertype assertions feels much lower).
Edit: perhaps the most succinct explanation of the issue is that the assertion implictly reads as follows: