At the engine level, casting to another class does not compare any property presence, it compares the unreal-level type info for the class.
You can have two classes that have exactly the same properties, and both derive straight from AActor, yet when you create an instance of class A, you cannot cast it to an instance of class B.
In C++, casting is fast, because it can be done with compiler support (although in debug mode it can run checks, depending on how you do it.)
In blueprint, is slightly slower, because of the blueprint/c++ marshaling needed, but it’s not terrible. What it can do is walk the chain of UClass in the object, to find the class you want, or not. I haven’t actually timed , but it’s never been a problem – if a blueprint-level cast is a performance problem, then that code shouldn’t be in blueprint to begin with.
You can read the code in Engine\Source\Editor\BlueprintGraph\Private\K2Node_DynamicCast.cpp
for more details (including the determination when you’re trying to do an impossible or tautological cast, based entirely on the UClass of the castee.)
And just to hammer home, is the implementation of the blueprint VM opcode EX_DynamicCast
:
// check to see if the Castee is a castable class
else if( Castee->IsA(ClassPtr) )
{
*(UObject**)RESULT_PARAM = Castee;
}
Which is the good-old Unreal C++ level cast. (There some additional code above to check for UInterface and NULL cases.)