Question

I have a shim based on ClassA.PropertyB, where PropertyB is of type ClassB. ClassA is internal and lives in another assembly from my test project. I've added a reference in the AssemblyInfo.cs so this internal can be seen by my test project and I'm able to create the shim.

I'd like to send the shimClassB instance into ClassA via the constructor:

public ClassA(object someInstance)
{
  PropertyB = (ClassB)someInstance;
} 

The above throws an InvalidCastException:

Unable to cast object of type shimClassB to type ClassB.

Is there some other technique that will get the shim instance into ClassA?

Was it helpful?

Solution

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;
} 

OTHER TIPS

I do not see any issues with doing that. Please verify that your property is of the correct type or try to assign some ShimClassB object to a new variable of type ClassB.

It might be helpful to show us your code, even though I just tried exact the same example without getting any exceptions.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top