It is important to note that ClassB
and ShimClassB
do not have a base class-derived class relationship. So the casts you are doing, might not be doing quite what you expect. You are seeing implicit conversions working due to user-defined conversions that Microsoft.Fakes have provided for you.
Your ShimClassB
inherits from ShimBase<T>
, where T is ClassB
. This class has a method that introduces a user-defined implicit conversion between ShimClassB
and ClassB
.
public static implicit operator T(ShimBase<T> shim)
When you attempt to do.
public ClassA(object someInstance)
{
PropertyB = (ClassB)someInstance;
}
you cannot have a cast to ClassB
as there is no conversion defined between object
and ClassB
.
From the C# Programming language specification 6.2.4 Explicit reference conversions:
For an explicit reference conversion to succeed at run-time, the value of the source operand must be null, or the actual type of the object referenced by the source operand must be a type that can be converted to the destination type by an implicit reference conversion (§6.1.6) or boxing conversion (§6.1.7). If an explicit reference conversion fails, a System.InvalidCastException is thrown.
You would find if your code had an intermediary cast it would no longer throw an InvalidCastException
however this is not a final solution as you don't want a cast to the Shim in your constructor:
public ClassA(object someInstance)
{
PropertyB = (ClassB)(ShimClassB)someInstance;
}
To solve this issue. I would advise changing your ClassA constructor so that it is typed and not accepting object
, when you pass your shimClassB into this constructor you will find the user-defined implicit conversion will be used:
// The user-defined implicit conversion takes care of this for us
ClassA(shimClassB);
public ClassA(ClassB someInstance)
{
PropertyB = someInstance;
}
or if you want to keep your constructor as it is:
ClassA((ClassB)shimClassB);
public ClassA(object someInstance)
{
PropertyB = (ClassB)someInstance;
}